V4.8.17 feature (#3485)
* feat: add third party account config (#3443) * temp * editor workflow variable style * add team to dispatch * i18n * delete console * change openai account position * fix * fix * fix * fix * fix * 4.8.17 test (#3461) * perf: external provider config * perf: ui * feat: add template config (#3434) * change template position * template config * delete console * delete * fix * fix * perf: Mongo visutal field (#3464) * remve invalid code * perf: team member visutal code * perf: virtual search; perf: search test data * fix: ts * fix: image response headers * perf: template code * perf: auth layout;perf: auto save (#3472) * perf: auth layout * perf: auto save * perf: auto save * fix: template guide display & http input support external variables (#3475) * fix: template guide display * http editor support external workflow variables * perf: auto save;fix: ifelse checker line break; (#3478) * perf: auto save * perf: auto save * fix: ifelse checker line break * perf: doc * perf: doc * fix: update var type error * 4.8.17 test (#3479) * perf: auto save * perf: auto save * perf: template code * 4.8.17 test (#3480) * perf: auto save * perf: auto save * perf: model price model * feat: add react memo * perf: model provider filter * fix: ts (#3481) * perf: auto save * perf: auto save * fix: ts * simple app tool select (#3473) * workflow plugin userguide & simple tool ui * simple tool filter * reuse component * change component to hook * fix * perf: too selector modal (#3484) * perf: auto save * perf: auto save * perf: markdown render * perf: too selector * fix: app version require tmbId * perf: templates refresh * perf: templates refresh * hide auto save error tip * perf: toolkit guide --------- Co-authored-by: heheer <heheer@sealos.io>
@@ -58,9 +58,9 @@ https://github.com/labring/FastGPT/assets/15308462/7d3a38df-eb0e-4388-9250-2409b
|
||||
- [x] 多库复用,混用
|
||||
- [x] chunk 记录修改和删除
|
||||
- [x] 支持手动输入,直接分段,QA 拆分导入
|
||||
- [x] 支持 txt,md,html,pdf,docx,pptx,csv,xlsx (有需要更多可 PR file loader)
|
||||
- [x] 支持 url 读取、CSV 批量导入
|
||||
- [x] 支持 txt,md,html,pdf,docx,pptx,csv,xlsx (有需要更多可 PR file loader),支持 url 读取、CSV 批量导入
|
||||
- [x] 混合检索 & 重排
|
||||
- [x] API 知识库
|
||||
- [ ] 自定义文件读取服务
|
||||
- [ ] 自定义分块服务
|
||||
|
||||
@@ -69,7 +69,7 @@ https://github.com/labring/FastGPT/assets/15308462/7d3a38df-eb0e-4388-9250-2409b
|
||||
- [x] 对话时反馈引用并可修改与删除
|
||||
- [x] 完整上下文呈现
|
||||
- [x] 完整模块中间值呈现
|
||||
- [x] 高级编排 DeBug 模式
|
||||
- [ ] 高级编排 DeBug 模式
|
||||
|
||||
`4` OpenAPI 接口
|
||||
- [x] completions 接口 (chat 模式对齐 GPT 接口)
|
||||
|
@@ -1424,7 +1424,11 @@ curl --location --request POST 'https://api.fastgpt.in/api/core/dataset/searchTe
|
||||
"limit": 5000,
|
||||
"similarity": 0,
|
||||
"searchMode": "embedding",
|
||||
"usingReRank": false
|
||||
"usingReRank": false,
|
||||
|
||||
"datasetSearchUsingExtensionQuery": true,
|
||||
"datasetSearchExtensionModel": "gpt-4o-mini",
|
||||
"datasetSearchExtensionBg": ""
|
||||
}'
|
||||
```
|
||||
|
||||
@@ -1441,6 +1445,9 @@ curl --location --request POST 'https://api.fastgpt.in/api/core/dataset/searchTe
|
||||
- similarity - 最低相关度(0~1,可选)
|
||||
- searchMode - 搜索模式:embedding | fullTextRecall | mixedRecall
|
||||
- usingReRank - 使用重排
|
||||
- datasetSearchUsingExtensionQuery - 使用问题优化
|
||||
- datasetSearchExtensionModel - 问题优化模型
|
||||
- datasetSearchExtensionBg - 问题优化背景描述
|
||||
{{% /alert %}}
|
||||
|
||||
{{< /markdownify >}}
|
||||
|
@@ -7,10 +7,30 @@ toc: true
|
||||
weight: 807
|
||||
---
|
||||
|
||||
## 运行升级脚本
|
||||
|
||||
从任意终端,发起 1 个 HTTP 请求。其中 {{rootkey}} 替换成环境变量里的 `rootkey`;{{host}} 替换成**FastGPT 域名**。
|
||||
|
||||
```bash
|
||||
curl --location --request POST 'https://{{host}}/api/admin/initv4817' \
|
||||
--header 'rootkey: {{rootkey}}' \
|
||||
--header 'Content-Type: application/json'
|
||||
```
|
||||
|
||||
会将用户绑定的 OpenAI 账号移动到团队中。
|
||||
|
||||
## 完整更新内容
|
||||
|
||||
1.
|
||||
2. 新增 - LLM 模型参数支持关闭 max_tokens 和 temperature。
|
||||
3. 优化 - 知识库搜索参数,滑动条支持输入模式,可以更精准的控制。
|
||||
4. 优化 - 可用模型展示
|
||||
1. 新增 - 简易模式工具调用支持数组类型插件。
|
||||
2. 新增 - 工作流增加异常离开自动保存,避免工作流丢失。
|
||||
3. 新增 - LLM 模型参数支持关闭 max_tokens 和 temperature。
|
||||
4. 新增 - 商业版支持后台配置模板市场。
|
||||
5. 新增 - 商业版支持后台配置自定义工作流变量,用于与业务系统鉴权打通。
|
||||
6. 新增 - 搜索测试接口支持问题优化。
|
||||
7. 优化 - Markdown 大小测试,超出 20 万字符不使用 Markdown 组件,避免崩溃。
|
||||
8. 优化 - 知识库搜索参数,滑动条支持输入模式,可以更精准的控制。
|
||||
9. 优化 - 可用模型展示
|
||||
10. 优化 - Mongo 查询语句,增加 virtual 字段。
|
||||
11. 修复 - 文件返回接口缺少 Content-Length 头,导致通过非同源文件上传时,阿里 vision 模型无法识别图片。
|
||||
12. 修复 - 去除判断器两端字符串隐藏换行符,避免判断器失效。
|
||||
13. 修复 - 变量更新节点,手动输入更新内容时候,非字符串类型数据类型无法自动转化。
|
@@ -18,6 +18,14 @@ export type NavbarItemType = {
|
||||
isActive: boolean;
|
||||
};
|
||||
|
||||
export type ExternalProviderWorkflowVarType = {
|
||||
name: string;
|
||||
key: string;
|
||||
intro: string;
|
||||
isOpen: boolean;
|
||||
url?: string;
|
||||
};
|
||||
|
||||
/* fastgpt main */
|
||||
export type FastGPTConfigFileType = {
|
||||
feConfigs: FastGPTFeConfigsType;
|
||||
@@ -84,6 +92,7 @@ export type FastGPTFeConfigsType = {
|
||||
uploadFileMaxSize?: number;
|
||||
lafEnv?: string;
|
||||
navbarItems?: NavbarItemType[];
|
||||
externalProviderWorkflowVariables?: ExternalProviderWorkflowVarType[];
|
||||
};
|
||||
|
||||
export type SystemEnvType = {
|
||||
|
26
packages/global/core/app/type.d.ts
vendored
@@ -13,6 +13,7 @@ import { StoreEdgeItemType } from '../workflow/type/edge';
|
||||
import { AppPermission } from '../../support/permission/app/controller';
|
||||
import { ParentIdType } from '../../common/parentFolder/type';
|
||||
import { FlowNodeInputTypeEnum } from 'core/workflow/node/constant';
|
||||
import { WorkflowTemplateBasicType } from '@fastgpt/global/core/workflow/type';
|
||||
|
||||
export type AppSchema = {
|
||||
_id: string;
|
||||
@@ -184,3 +185,28 @@ export type SystemPluginListItemType = {
|
||||
name: string;
|
||||
avatar: string;
|
||||
};
|
||||
|
||||
export type AppTemplateSchemaType = {
|
||||
templateId: string;
|
||||
name: string;
|
||||
intro: string;
|
||||
avatar: string;
|
||||
tags: string[];
|
||||
type: string;
|
||||
author?: string;
|
||||
isActive?: boolean;
|
||||
userGuide?: {
|
||||
type: 'markdown' | 'link';
|
||||
content?: string;
|
||||
link?: string;
|
||||
};
|
||||
isQuickTemplate?: boolean;
|
||||
order?: number;
|
||||
workflow: WorkflowTemplateBasicType;
|
||||
};
|
||||
|
||||
export type TemplateTypeSchemaType = {
|
||||
typeName: string;
|
||||
typeId: string;
|
||||
typeOrder: number;
|
||||
};
|
||||
|
@@ -1,9 +1,7 @@
|
||||
import { DatasetCollectionTypeEnum, TrainingModeEnum, TrainingTypeMap } from '../constants';
|
||||
import { CollectionWithDatasetType, DatasetCollectionSchemaType } from '../type';
|
||||
import { DatasetCollectionSchemaType } from '../type';
|
||||
|
||||
export const getCollectionSourceData = (
|
||||
collection?: CollectionWithDatasetType | DatasetCollectionSchemaType
|
||||
) => {
|
||||
export const getCollectionSourceData = (collection?: DatasetCollectionSchemaType) => {
|
||||
return {
|
||||
sourceId:
|
||||
collection?.fileId ||
|
||||
|
7
packages/global/core/dataset/type.d.ts
vendored
@@ -133,11 +133,8 @@ export type DatasetTrainingSchemaType = {
|
||||
indexes: Omit<DatasetDataIndexItemType, 'dataId'>[];
|
||||
};
|
||||
|
||||
export type CollectionWithDatasetType = Omit<DatasetCollectionSchemaType, 'datasetId'> & {
|
||||
datasetId: DatasetSchemaType;
|
||||
};
|
||||
export type DatasetDataWithCollectionType = Omit<DatasetDataSchemaType, 'collectionId'> & {
|
||||
collectionId: DatasetCollectionSchemaType;
|
||||
export type CollectionWithDatasetType = DatasetCollectionSchemaType & {
|
||||
dataset: DatasetSchemaType;
|
||||
};
|
||||
|
||||
/* ================= dataset ===================== */
|
||||
|
@@ -21,13 +21,20 @@ import { ReadFileNodeResponse } from '../template/system/readFiles/type';
|
||||
import { UserSelectOptionType } from '../template/system/userSelect/type';
|
||||
import { WorkflowResponseType } from '../../../../service/core/workflow/dispatch/type';
|
||||
import { AiChatQuoteRoleType } from '../template/system/aiChat/type';
|
||||
import { LafAccountType, OpenaiAccountType } from '../../../support/user/team/type';
|
||||
|
||||
export type ExternalProviderType = {
|
||||
openaiAccount?: OpenaiAccountType;
|
||||
externalWorkflowVariables?: Record<string, string>;
|
||||
};
|
||||
|
||||
/* workflow props */
|
||||
export type ChatDispatchProps = {
|
||||
res?: NextApiResponse;
|
||||
requestOrigin?: string;
|
||||
mode: 'test' | 'chat' | 'debug';
|
||||
user: UserModelSchema;
|
||||
timezone: string;
|
||||
externalProvider: ExternalProviderType;
|
||||
|
||||
runningAppInfo: {
|
||||
id: string; // May be the id of the system plug-in (cannot be used directly to look up the table)
|
||||
|
@@ -9,6 +9,7 @@ import { isValidReferenceValueFormat } from '../utils';
|
||||
import { FlowNodeOutputItemType, ReferenceValueType } from '../type/io';
|
||||
import { ChatItemType, NodeOutputItemType } from '../../../core/chat/type';
|
||||
import { ChatItemValueTypeEnum, ChatRoleEnum } from '../../../core/chat/constants';
|
||||
import { replaceVariable } from '../../../common/string/tools';
|
||||
|
||||
export const getMaxHistoryLimitFromNodes = (nodes: StoreNodeItemType[]): number => {
|
||||
let limit = 10;
|
||||
@@ -317,6 +318,8 @@ export function replaceEditorVariable({
|
||||
}) {
|
||||
if (typeof text !== 'string') return text;
|
||||
|
||||
text = replaceVariable(text, variables);
|
||||
|
||||
const variablePattern = /\{\{\$([^.]+)\.([^$]+)\$\}\}/g;
|
||||
const matches = [...text.matchAll(variablePattern)];
|
||||
if (matches.length === 0) return text;
|
||||
|
@@ -30,7 +30,6 @@ export const WorkflowStart: FlowNodeTemplateType = {
|
||||
intro: '',
|
||||
forbidDelete: true,
|
||||
unique: true,
|
||||
courseUrl: '/docs/guide/workbench/workflow/input/',
|
||||
version: '481',
|
||||
inputs: [{ ...Input_Template_UserChatInput, toolDescription: i18nT('workflow:user_question') }],
|
||||
outputs: [
|
||||
|
2
packages/global/core/workflow/type/node.d.ts
vendored
@@ -69,6 +69,7 @@ export type FlowNodeTemplateType = FlowNodeCommonType & {
|
||||
|
||||
diagram?: string; // diagram url
|
||||
courseUrl?: string; // course url
|
||||
userGuide?: string; // user guide
|
||||
};
|
||||
|
||||
export type NodeTemplateListItemType = {
|
||||
@@ -87,6 +88,7 @@ export type NodeTemplateListItemType = {
|
||||
currentCost?: number; // 当前积分消耗
|
||||
hasTokenFee?: boolean; // 是否配置积分
|
||||
instructions?: string; // 使用说明
|
||||
courseUrl?: string; // 教程链接
|
||||
};
|
||||
|
||||
export type NodeTemplateListType = {
|
||||
|
5
packages/global/support/outLink/type.d.ts
vendored
@@ -83,11 +83,6 @@ export type OutLinkSchema<T extends OutlinkAppType = undefined> = {
|
||||
app: T;
|
||||
};
|
||||
|
||||
// to handle MongoDB querying
|
||||
export type OutLinkWithAppType = Omit<OutLinkSchema, 'appId'> & {
|
||||
appId: AppSchema;
|
||||
};
|
||||
|
||||
// Edit the Outlink
|
||||
export type OutLinkEditType<T = undefined> = {
|
||||
_id?: string;
|
||||
|
9
packages/global/support/permission/type.d.ts
vendored
@@ -1,5 +1,6 @@
|
||||
import { UserModelSchema } from '../user/type';
|
||||
import { RequireOnlyOne } from '../../common/type/utils';
|
||||
import { TeamMemberWithUserSchema } from '../user/team/type';
|
||||
import { TeamMemberSchema } from '../user/team/type';
|
||||
import { AuthUserTypeEnum, PermissionKeyEnum, PerResourceTypeEnum } from './constant';
|
||||
import { MemberGroupSchemaType } from './memberGroup/type';
|
||||
|
||||
@@ -31,11 +32,7 @@ export type ResourcePermissionType = {
|
||||
}>;
|
||||
|
||||
export type ResourcePerWithTmbWithUser = Omit<ResourcePermissionType, 'tmbId'> & {
|
||||
tmbId: TeamMemberWithUserSchema;
|
||||
};
|
||||
|
||||
export type ResourcePerWithGroup = Omit<ResourcePermissionType, 'groupId'> & {
|
||||
groupId: MemberGroupSchemaType;
|
||||
tmbId: TeamMemberSchema & { user: UserModelSchema };
|
||||
};
|
||||
|
||||
export type PermissionSchemaType = {
|
||||
|
@@ -1,6 +1,6 @@
|
||||
import { PermissionValueType } from '../../permission/type';
|
||||
import { TeamMemberRoleEnum } from './constant';
|
||||
import { LafAccountType, TeamMemberSchema } from './type';
|
||||
import { LafAccountType, TeamMemberSchema, ThirdPartyAccountType } from './type';
|
||||
|
||||
export type AuthTeamRoleProps = {
|
||||
teamId: string;
|
||||
@@ -11,14 +11,13 @@ export type CreateTeamProps = {
|
||||
name: string;
|
||||
avatar?: string;
|
||||
defaultTeam?: boolean;
|
||||
lafAccount?: LafAccountType;
|
||||
memberName?: string;
|
||||
};
|
||||
export type UpdateTeamProps = {
|
||||
export type UpdateTeamProps = Omit<ThirdPartyAccountType, 'externalWorkflowVariable'> & {
|
||||
name?: string;
|
||||
avatar?: string;
|
||||
teamDomain?: string;
|
||||
lafAccount?: null | LafAccountType;
|
||||
externalWorkflowVariable?: { key: string; value: string };
|
||||
};
|
||||
|
||||
/* ------------- member ----------- */
|
||||
|
32
packages/global/support/user/team/type.d.ts
vendored
@@ -4,6 +4,12 @@ import { LafAccountType } from './type';
|
||||
import { PermissionValueType, ResourcePermissionType } from '../../permission/type';
|
||||
import { TeamPermission } from '../../permission/user/controller';
|
||||
|
||||
export type ThirdPartyAccountType = {
|
||||
lafAccount?: LafAccountType;
|
||||
openaiAccount?: OpenaiAccountType;
|
||||
externalWorkflowVariables?: Record<string, string>;
|
||||
};
|
||||
|
||||
export type TeamSchema = {
|
||||
_id: string;
|
||||
name: string;
|
||||
@@ -16,9 +22,8 @@ export type TeamSchema = {
|
||||
lastExportDatasetTime: Date;
|
||||
lastWebsiteSyncTime: Date;
|
||||
};
|
||||
lafAccount: LafAccountType;
|
||||
notificationAccount?: string;
|
||||
};
|
||||
} & ThirdPartyAccountType;
|
||||
|
||||
export type tagsType = {
|
||||
label: string;
|
||||
@@ -42,16 +47,9 @@ export type TeamMemberSchema = {
|
||||
defaultTeam: boolean;
|
||||
};
|
||||
|
||||
export type TeamMemberWithUserSchema = Omit<TeamMemberSchema, 'userId'> & {
|
||||
userId: UserModelSchema;
|
||||
};
|
||||
|
||||
export type TeamMemberWithTeamSchema = Omit<TeamMemberSchema, 'teamId'> & {
|
||||
teamId: TeamSchema;
|
||||
};
|
||||
|
||||
export type TeamMemberWithTeamAndUserSchema = Omit<TeamMemberWithTeamSchema, 'userId'> & {
|
||||
userId: UserModelSchema;
|
||||
export type TeamMemberWithTeamAndUserSchema = TeamMemberSchema & {
|
||||
team: TeamSchema;
|
||||
user: UserModelSchema;
|
||||
};
|
||||
|
||||
export type TeamTmbItemType = {
|
||||
@@ -66,10 +64,9 @@ export type TeamTmbItemType = {
|
||||
defaultTeam: boolean;
|
||||
role: `${TeamMemberRoleEnum}`;
|
||||
status: `${TeamMemberStatusEnum}`;
|
||||
lafAccount?: LafAccountType;
|
||||
notificationAccount?: string;
|
||||
permission: TeamPermission;
|
||||
};
|
||||
} & ThirdPartyAccountType;
|
||||
|
||||
export type TeamMemberItemType = {
|
||||
userId: string;
|
||||
@@ -88,11 +85,16 @@ export type TeamTagItemType = {
|
||||
};
|
||||
|
||||
export type LafAccountType = {
|
||||
token: string;
|
||||
appid: string;
|
||||
token: string;
|
||||
pat: string;
|
||||
};
|
||||
|
||||
export type OpenaiAccountType = {
|
||||
key: string;
|
||||
baseUrl: string;
|
||||
};
|
||||
|
||||
export type TeamInvoiceHeaderType = {
|
||||
teamName: string;
|
||||
unifiedCreditCode: string;
|
||||
|
5
packages/global/support/user/type.d.ts
vendored
@@ -14,10 +14,6 @@ export type UserModelSchema = {
|
||||
timezone: string;
|
||||
status: `${UserStatusEnum}`;
|
||||
lastLoginTmbId?: string;
|
||||
openaiAccount?: {
|
||||
key: string;
|
||||
baseUrl: string;
|
||||
};
|
||||
fastgpt_sem?: {
|
||||
keyword: string;
|
||||
};
|
||||
@@ -29,7 +25,6 @@ export type UserType = {
|
||||
avatar: string;
|
||||
timezone: string;
|
||||
promotionRate: UserModelSchema['promotionRate'];
|
||||
openaiAccount: UserModelSchema['openaiAccount'];
|
||||
team: TeamTmbItemType;
|
||||
standardInfo?: standardInfoType;
|
||||
notificationAccount?: string;
|
||||
|
@@ -55,8 +55,7 @@
|
||||
"maxFiles": 5,
|
||||
"canSelectFile": true,
|
||||
"canSelectImg": true,
|
||||
"required": true,
|
||||
"toolDescription": "部署的searXNG服务的链接"
|
||||
"required": true
|
||||
}
|
||||
],
|
||||
"outputs": [
|
||||
|
@@ -1,4 +1,3 @@
|
||||
import type { UserModelSchema } from '@fastgpt/global/support/user/type';
|
||||
import OpenAI from '@fastgpt/global/core/ai';
|
||||
import {
|
||||
ChatCompletionCreateParamsNonStreaming,
|
||||
@@ -7,13 +6,11 @@ import {
|
||||
import { getErrText } from '@fastgpt/global/common/error/utils';
|
||||
import { addLog } from '../../common/system/log';
|
||||
import { i18nT } from '../../../web/i18n/utils';
|
||||
import { OpenaiAccountType } from '@fastgpt/global/support/user/team/type';
|
||||
|
||||
export const openaiBaseUrl = process.env.OPENAI_BASE_URL || 'https://api.openai.com/v1';
|
||||
|
||||
export const getAIApi = (props?: {
|
||||
userKey?: UserModelSchema['openaiAccount'];
|
||||
timeout?: number;
|
||||
}) => {
|
||||
export const getAIApi = (props?: { userKey?: OpenaiAccountType; timeout?: number }) => {
|
||||
const { userKey, timeout } = props || {};
|
||||
|
||||
const baseUrl =
|
||||
@@ -29,7 +26,7 @@ export const getAIApi = (props?: {
|
||||
});
|
||||
};
|
||||
|
||||
export const getAxiosConfig = (props?: { userKey?: UserModelSchema['openaiAccount'] }) => {
|
||||
export const getAxiosConfig = (props?: { userKey?: OpenaiAccountType }) => {
|
||||
const { userKey } = props || {};
|
||||
|
||||
const baseUrl =
|
||||
@@ -57,7 +54,7 @@ export const createChatCompletion = async <T extends CompletionsBodyType>({
|
||||
options
|
||||
}: {
|
||||
body: T;
|
||||
userKey?: UserModelSchema['openaiAccount'];
|
||||
userKey?: OpenaiAccountType;
|
||||
timeout?: number;
|
||||
options?: OpenAI.RequestOptions;
|
||||
}): Promise<{
|
||||
|
@@ -131,6 +131,7 @@ export async function getChildAppPreviewNode({
|
||||
name: app.name,
|
||||
intro: app.intro,
|
||||
courseUrl: app.courseUrl,
|
||||
userGuide: app.userGuide,
|
||||
showStatus: app.showStatus,
|
||||
isTool: true,
|
||||
version: app.version,
|
||||
|
51
packages/service/core/app/templates/templateSchema.ts
Normal file
@@ -0,0 +1,51 @@
|
||||
import { AppTemplateSchemaType } from '@fastgpt/global/core/app/type';
|
||||
import { connectionMongo, getMongoModel } from '../../../common/mongo/index';
|
||||
const { Schema } = connectionMongo;
|
||||
|
||||
export const collectionName = 'app_templates';
|
||||
|
||||
const AppTemplateSchema = new Schema({
|
||||
templateId: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
name: {
|
||||
type: String
|
||||
},
|
||||
intro: {
|
||||
type: String
|
||||
},
|
||||
avatar: {
|
||||
type: String
|
||||
},
|
||||
tags: {
|
||||
type: [String],
|
||||
default: undefined
|
||||
},
|
||||
type: {
|
||||
type: String
|
||||
},
|
||||
isActive: {
|
||||
type: Boolean
|
||||
},
|
||||
userGuide: {
|
||||
type: Object
|
||||
},
|
||||
isQuickTemplate: {
|
||||
type: Boolean
|
||||
},
|
||||
order: {
|
||||
type: Number,
|
||||
default: -1
|
||||
},
|
||||
workflow: {
|
||||
type: Object
|
||||
}
|
||||
});
|
||||
|
||||
AppTemplateSchema.index({ templateId: 1 });
|
||||
|
||||
export const MongoAppTemplate = getMongoModel<AppTemplateSchemaType>(
|
||||
collectionName,
|
||||
AppTemplateSchema
|
||||
);
|
25
packages/service/core/app/templates/templateTypeSchema.ts
Normal file
@@ -0,0 +1,25 @@
|
||||
import { TemplateTypeSchemaType } from '@fastgpt/global/core/app/type';
|
||||
import { connectionMongo, getMongoModel } from '../../../common/mongo/index';
|
||||
const { Schema } = connectionMongo;
|
||||
|
||||
export const collectionName = 'app_template_types';
|
||||
|
||||
const TemplateTypeSchema = new Schema({
|
||||
typeName: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
typeId: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
typeOrder: {
|
||||
type: Number,
|
||||
default: 0
|
||||
}
|
||||
});
|
||||
|
||||
export const MongoTemplateTypes = getMongoModel<TemplateTypeSchemaType>(
|
||||
collectionName,
|
||||
TemplateTypeSchema
|
||||
);
|
@@ -2,10 +2,16 @@ import { connectionMongo, getMongoModel, type Model } from '../../../common/mong
|
||||
const { Schema, model, models } = connectionMongo;
|
||||
import { AppVersionSchemaType } from '@fastgpt/global/core/app/version';
|
||||
import { chatConfigType } from '../schema';
|
||||
import { TeamMemberCollectionName } from '@fastgpt/global/support/user/team/constant';
|
||||
|
||||
export const AppVersionCollectionName = 'app_versions';
|
||||
|
||||
const AppVersionSchema = new Schema({
|
||||
tmbId: {
|
||||
type: String,
|
||||
ref: TeamMemberCollectionName,
|
||||
required: true
|
||||
},
|
||||
appId: {
|
||||
type: Schema.Types.ObjectId,
|
||||
ref: AppVersionCollectionName,
|
||||
@@ -26,16 +32,8 @@ const AppVersionSchema = new Schema({
|
||||
chatConfig: {
|
||||
type: chatConfigType
|
||||
},
|
||||
isPublish: {
|
||||
type: Boolean
|
||||
},
|
||||
versionName: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
tmbId: {
|
||||
type: String
|
||||
}
|
||||
isPublish: Boolean,
|
||||
versionName: String
|
||||
});
|
||||
|
||||
try {
|
||||
|
@@ -104,9 +104,6 @@ export const loadRequestMessages = async ({
|
||||
}) => {
|
||||
// Load image to base64
|
||||
const loadImageToBase64 = async (messages: ChatCompletionContentPart[]) => {
|
||||
if (process.env.MULTIPLE_DATA_TO_BASE64 === 'false') {
|
||||
return messages;
|
||||
}
|
||||
return Promise.all(
|
||||
messages.map(async (item) => {
|
||||
if (item.type === 'image_url') {
|
||||
@@ -125,7 +122,7 @@ export const loadRequestMessages = async ({
|
||||
|
||||
try {
|
||||
// If imgUrl is a local path, load image from local, and set url to base64
|
||||
if (imgUrl.startsWith('/')) {
|
||||
if (imgUrl.startsWith('/') || process.env.MULTIPLE_DATA_TO_BASE64 === 'true') {
|
||||
addLog.debug('Load image from local server', {
|
||||
baseUrl: serverRequestBaseUrl,
|
||||
requestUrl: imgUrl
|
||||
|
@@ -4,11 +4,7 @@ import {
|
||||
} from '@fastgpt/global/core/dataset/constants';
|
||||
import type { CreateDatasetCollectionParams } from '@fastgpt/global/core/dataset/api.d';
|
||||
import { MongoDatasetCollection } from './schema';
|
||||
import {
|
||||
CollectionWithDatasetType,
|
||||
DatasetCollectionSchemaType,
|
||||
DatasetSchemaType
|
||||
} from '@fastgpt/global/core/dataset/type';
|
||||
import { DatasetCollectionSchemaType, DatasetSchemaType } from '@fastgpt/global/core/dataset/type';
|
||||
import { MongoDatasetTraining } from '../training/schema';
|
||||
import { MongoDatasetData } from '../data/schema';
|
||||
import { delImgByRelatedId } from '../../../common/file/image/controller';
|
||||
@@ -230,7 +226,7 @@ export const delCollectionRelatedSource = async ({
|
||||
collections,
|
||||
session
|
||||
}: {
|
||||
collections: (CollectionWithDatasetType | DatasetCollectionSchemaType)[];
|
||||
collections: DatasetCollectionSchemaType[];
|
||||
session: ClientSession;
|
||||
}) => {
|
||||
if (collections.length === 0) return;
|
||||
@@ -264,7 +260,7 @@ export async function delCollection({
|
||||
session,
|
||||
delRelatedSource
|
||||
}: {
|
||||
collections: (CollectionWithDatasetType | DatasetCollectionSchemaType)[];
|
||||
collections: DatasetCollectionSchemaType[];
|
||||
session: ClientSession;
|
||||
delRelatedSource: boolean;
|
||||
}) {
|
||||
@@ -274,16 +270,7 @@ export async function delCollection({
|
||||
|
||||
if (!teamId) return Promise.reject('teamId is not exist');
|
||||
|
||||
const datasetIds = Array.from(
|
||||
new Set(
|
||||
collections.map((item) => {
|
||||
if (typeof item.datasetId === 'string') {
|
||||
return String(item.datasetId);
|
||||
}
|
||||
return String(item.datasetId._id);
|
||||
})
|
||||
)
|
||||
);
|
||||
const datasetIds = Array.from(new Set(collections.map((item) => String(item.datasetId))));
|
||||
const collectionIds = collections.map((item) => String(item._id));
|
||||
|
||||
// delete training data
|
||||
@@ -324,7 +311,7 @@ export async function delOnlyCollection({
|
||||
collections,
|
||||
session
|
||||
}: {
|
||||
collections: (CollectionWithDatasetType | DatasetCollectionSchemaType)[];
|
||||
collections: DatasetCollectionSchemaType[];
|
||||
session: ClientSession;
|
||||
}) {
|
||||
if (collections.length === 0) return;
|
||||
@@ -333,16 +320,7 @@ export async function delOnlyCollection({
|
||||
|
||||
if (!teamId) return Promise.reject('teamId is not exist');
|
||||
|
||||
const datasetIds = Array.from(
|
||||
new Set(
|
||||
collections.map((item) => {
|
||||
if (typeof item.datasetId === 'string') {
|
||||
return String(item.datasetId);
|
||||
}
|
||||
return String(item.datasetId._id);
|
||||
})
|
||||
)
|
||||
);
|
||||
const datasetIds = Array.from(new Set(collections.map((item) => String(item.datasetId))));
|
||||
const collectionIds = collections.map((item) => String(item._id));
|
||||
|
||||
// delete training data
|
||||
|
@@ -100,6 +100,13 @@ const DatasetCollectionSchema = new Schema({
|
||||
}
|
||||
});
|
||||
|
||||
DatasetCollectionSchema.virtual('dataset', {
|
||||
ref: DatasetCollectionName,
|
||||
localField: 'datasetId',
|
||||
foreignField: '_id',
|
||||
justOne: true
|
||||
});
|
||||
|
||||
try {
|
||||
// auth file
|
||||
DatasetCollectionSchema.index({ teamId: 1, fileId: 1 });
|
||||
|
@@ -130,7 +130,7 @@ export const collectionTagsToTagLabel = async ({
|
||||
};
|
||||
|
||||
export const syncCollection = async (collection: CollectionWithDatasetType) => {
|
||||
const dataset = collection.datasetId;
|
||||
const dataset = collection.dataset;
|
||||
|
||||
if (
|
||||
collection.type !== DatasetCollectionTypeEnum.link &&
|
||||
@@ -183,7 +183,7 @@ export const syncCollection = async (collection: CollectionWithDatasetType) => {
|
||||
teamId: collection.teamId,
|
||||
tmbId: collection.tmbId,
|
||||
name: collection.name,
|
||||
datasetId: collection.datasetId._id,
|
||||
datasetId: collection.datasetId,
|
||||
parentId: collection.parentId,
|
||||
type: collection.type,
|
||||
|
||||
|
@@ -1,4 +1,4 @@
|
||||
import { CollectionWithDatasetType, DatasetSchemaType } from '@fastgpt/global/core/dataset/type';
|
||||
import { DatasetSchemaType } from '@fastgpt/global/core/dataset/type';
|
||||
import { MongoDatasetCollection } from './collection/schema';
|
||||
import { MongoDataset } from './schema';
|
||||
import { delCollectionRelatedSource } from './collection/controller';
|
||||
@@ -49,9 +49,9 @@ export async function findDatasetAndAllChildren({
|
||||
}
|
||||
|
||||
export async function getCollectionWithDataset(collectionId: string) {
|
||||
const data = (await MongoDatasetCollection.findById(collectionId)
|
||||
.populate('datasetId')
|
||||
.lean()) as CollectionWithDatasetType;
|
||||
const data = await MongoDatasetCollection.findById(collectionId)
|
||||
.populate<{ dataset: DatasetSchemaType }>('dataset')
|
||||
.lean();
|
||||
if (!data) {
|
||||
return Promise.reject('Collection is not exist');
|
||||
}
|
||||
|
@@ -77,21 +77,32 @@ const DatasetDataSchema = new Schema({
|
||||
rebuilding: Boolean
|
||||
});
|
||||
|
||||
// list collection and count data; list data; delete collection(relate data)
|
||||
DatasetDataSchema.index({
|
||||
teamId: 1,
|
||||
datasetId: 1,
|
||||
collectionId: 1,
|
||||
chunkIndex: 1,
|
||||
updateTime: -1
|
||||
DatasetDataSchema.virtual('collection', {
|
||||
ref: DatasetColCollectionName,
|
||||
localField: 'collectionId',
|
||||
foreignField: '_id',
|
||||
justOne: true
|
||||
});
|
||||
// full text index
|
||||
DatasetDataSchema.index({ teamId: 1, datasetId: 1, fullTextToken: 'text' });
|
||||
// Recall vectors after data matching
|
||||
DatasetDataSchema.index({ teamId: 1, datasetId: 1, collectionId: 1, 'indexes.dataId': 1 });
|
||||
DatasetDataSchema.index({ updateTime: 1 });
|
||||
// rebuild data
|
||||
DatasetDataSchema.index({ rebuilding: 1, teamId: 1, datasetId: 1 });
|
||||
|
||||
try {
|
||||
// list collection and count data; list data; delete collection(relate data)
|
||||
DatasetDataSchema.index({
|
||||
teamId: 1,
|
||||
datasetId: 1,
|
||||
collectionId: 1,
|
||||
chunkIndex: 1,
|
||||
updateTime: -1
|
||||
});
|
||||
// full text index
|
||||
DatasetDataSchema.index({ teamId: 1, datasetId: 1, fullTextToken: 'text' });
|
||||
// Recall vectors after data matching
|
||||
DatasetDataSchema.index({ teamId: 1, datasetId: 1, collectionId: 1, 'indexes.dataId': 1 });
|
||||
DatasetDataSchema.index({ updateTime: 1 });
|
||||
// rebuild data
|
||||
DatasetDataSchema.index({ rebuilding: 1, teamId: 1, datasetId: 1 });
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
|
||||
export const MongoDatasetData = getMongoModel<DatasetDataSchemaType>(
|
||||
DatasetDataCollectionName,
|
||||
|
@@ -8,8 +8,8 @@ import { getVectorsByText } from '../../ai/embedding';
|
||||
import { getVectorModel } from '../../ai/model';
|
||||
import { MongoDatasetData } from '../data/schema';
|
||||
import {
|
||||
DatasetCollectionSchemaType,
|
||||
DatasetDataSchemaType,
|
||||
DatasetDataWithCollectionType,
|
||||
SearchDataResponseItemType
|
||||
} from '@fastgpt/global/core/dataset/type';
|
||||
import { MongoDatasetCollection } from '../collection/schema';
|
||||
@@ -267,7 +267,7 @@ export async function searchDatasetData(props: SearchDatasetDataProps) {
|
||||
});
|
||||
|
||||
// get q and a
|
||||
const dataList = (await MongoDatasetData.find(
|
||||
const dataList = await MongoDatasetData.find(
|
||||
{
|
||||
teamId,
|
||||
datasetId: { $in: datasetIds },
|
||||
@@ -276,8 +276,11 @@ export async function searchDatasetData(props: SearchDatasetDataProps) {
|
||||
},
|
||||
'datasetId collectionId updateTime q a chunkIndex indexes'
|
||||
)
|
||||
.populate('collectionId', 'name fileId rawLink externalFileId externalFileUrl')
|
||||
.lean()) as DatasetDataWithCollectionType[];
|
||||
.populate<{ collection: DatasetCollectionSchemaType }>(
|
||||
'collection',
|
||||
'name fileId rawLink externalFileId externalFileUrl'
|
||||
)
|
||||
.lean();
|
||||
|
||||
// add score to data(It's already sorted. The first one is the one with the most points)
|
||||
const concatResults = dataList.map((data) => {
|
||||
@@ -307,8 +310,8 @@ export async function searchDatasetData(props: SearchDatasetDataProps) {
|
||||
a: data.a,
|
||||
chunkIndex: data.chunkIndex,
|
||||
datasetId: String(data.datasetId),
|
||||
collectionId: String(data.collectionId?._id),
|
||||
...getCollectionSourceData(data.collectionId),
|
||||
collectionId: String(data.collectionId),
|
||||
...getCollectionSourceData(data.collection),
|
||||
score: [{ type: SearchScoreTypeEnum.embedding, value: data.score, index }]
|
||||
};
|
||||
|
||||
|
@@ -34,7 +34,7 @@ export const pushDataListToTrainingQueueByCollectionId = async ({
|
||||
session?: ClientSession;
|
||||
} & PushDatasetDataProps) => {
|
||||
const {
|
||||
datasetId: { _id: datasetId, agentModel, vectorModel }
|
||||
dataset: { _id: datasetId, agentModel, vectorModel }
|
||||
} = await getCollectionWithDataset(collectionId);
|
||||
return pushDataListToTrainingQueue({
|
||||
...props,
|
||||
|
@@ -35,7 +35,7 @@ type ActionProps = Props & { cqModel: LLMModelItemType };
|
||||
/* request openai chat */
|
||||
export const dispatchClassifyQuestion = async (props: Props): Promise<CQResponse> => {
|
||||
const {
|
||||
user,
|
||||
externalProvider,
|
||||
node: { nodeId, name },
|
||||
histories,
|
||||
params: { model, history = 6, agents, userChatInput }
|
||||
@@ -69,7 +69,7 @@ export const dispatchClassifyQuestion = async (props: Props): Promise<CQResponse
|
||||
.filter((item) => item.key !== result.key)
|
||||
.map((item) => getHandleId(nodeId, 'source', item.key)),
|
||||
[DispatchNodeResponseKeyEnum.nodeResponse]: {
|
||||
totalPoints: user.openaiAccount?.key ? 0 : totalPoints,
|
||||
totalPoints: externalProvider.openaiAccount?.key ? 0 : totalPoints,
|
||||
model: modelName,
|
||||
query: userChatInput,
|
||||
tokens,
|
||||
@@ -80,7 +80,7 @@ export const dispatchClassifyQuestion = async (props: Props): Promise<CQResponse
|
||||
[DispatchNodeResponseKeyEnum.nodeDispatchUsages]: [
|
||||
{
|
||||
moduleName: name,
|
||||
totalPoints: user.openaiAccount?.key ? 0 : totalPoints,
|
||||
totalPoints: externalProvider.openaiAccount?.key ? 0 : totalPoints,
|
||||
model: modelName,
|
||||
tokens
|
||||
}
|
||||
@@ -90,7 +90,7 @@ export const dispatchClassifyQuestion = async (props: Props): Promise<CQResponse
|
||||
|
||||
const completions = async ({
|
||||
cqModel,
|
||||
user,
|
||||
externalProvider,
|
||||
histories,
|
||||
params: { agents, systemPrompt = '', userChatInput }
|
||||
}: ActionProps) => {
|
||||
@@ -131,7 +131,7 @@ const completions = async ({
|
||||
},
|
||||
cqModel
|
||||
),
|
||||
userKey: user.openaiAccount
|
||||
userKey: externalProvider.openaiAccount
|
||||
});
|
||||
const answer = data.choices?.[0].message?.content || '';
|
||||
|
||||
|
@@ -46,7 +46,7 @@ const agentFunName = 'request_function';
|
||||
|
||||
export async function dispatchContentExtract(props: Props): Promise<Response> {
|
||||
const {
|
||||
user,
|
||||
externalProvider,
|
||||
node: { name },
|
||||
histories,
|
||||
params: { content, history = 6, model, description, extractKeys }
|
||||
@@ -123,7 +123,7 @@ export async function dispatchContentExtract(props: Props): Promise<Response> {
|
||||
[NodeOutputKeyEnum.contextExtractFields]: JSON.stringify(arg),
|
||||
...arg,
|
||||
[DispatchNodeResponseKeyEnum.nodeResponse]: {
|
||||
totalPoints: user.openaiAccount?.key ? 0 : totalPoints,
|
||||
totalPoints: externalProvider.openaiAccount?.key ? 0 : totalPoints,
|
||||
model: modelName,
|
||||
query: content,
|
||||
tokens,
|
||||
@@ -134,7 +134,7 @@ export async function dispatchContentExtract(props: Props): Promise<Response> {
|
||||
[DispatchNodeResponseKeyEnum.nodeDispatchUsages]: [
|
||||
{
|
||||
moduleName: name,
|
||||
totalPoints: user.openaiAccount?.key ? 0 : totalPoints,
|
||||
totalPoints: externalProvider.openaiAccount?.key ? 0 : totalPoints,
|
||||
model: modelName,
|
||||
tokens
|
||||
}
|
||||
@@ -211,7 +211,7 @@ ${description ? `- ${description}` : ''}
|
||||
};
|
||||
|
||||
const toolChoice = async (props: ActionProps) => {
|
||||
const { user, extractModel } = props;
|
||||
const { externalProvider, extractModel } = props;
|
||||
|
||||
const { filterMessages, agentFunction } = await getFunctionCallSchema(props);
|
||||
|
||||
@@ -233,7 +233,7 @@ const toolChoice = async (props: ActionProps) => {
|
||||
},
|
||||
extractModel
|
||||
),
|
||||
userKey: user.openaiAccount
|
||||
userKey: externalProvider.openaiAccount
|
||||
});
|
||||
|
||||
const arg: Record<string, any> = (() => {
|
||||
@@ -263,7 +263,7 @@ const toolChoice = async (props: ActionProps) => {
|
||||
};
|
||||
|
||||
const functionCall = async (props: ActionProps) => {
|
||||
const { user, extractModel } = props;
|
||||
const { externalProvider, extractModel } = props;
|
||||
|
||||
const { agentFunction, filterMessages } = await getFunctionCallSchema(props);
|
||||
const functions: ChatCompletionCreateParams.Function[] = [agentFunction];
|
||||
@@ -281,7 +281,7 @@ const functionCall = async (props: ActionProps) => {
|
||||
},
|
||||
extractModel
|
||||
),
|
||||
userKey: user.openaiAccount
|
||||
userKey: externalProvider.openaiAccount
|
||||
});
|
||||
|
||||
try {
|
||||
@@ -312,7 +312,7 @@ const functionCall = async (props: ActionProps) => {
|
||||
|
||||
const completions = async ({
|
||||
extractModel,
|
||||
user,
|
||||
externalProvider,
|
||||
histories,
|
||||
params: { content, extractKeys, description = 'No special requirements' }
|
||||
}: ActionProps) => {
|
||||
@@ -360,7 +360,7 @@ Human: ${content}`
|
||||
},
|
||||
extractModel
|
||||
),
|
||||
userKey: user.openaiAccount
|
||||
userKey: externalProvider.openaiAccount
|
||||
});
|
||||
const answer = data.choices?.[0].message?.content || '';
|
||||
|
||||
|
@@ -43,7 +43,7 @@ export const runToolWithFunctionCall = async (
|
||||
requestOrigin,
|
||||
runtimeNodes,
|
||||
runtimeEdges,
|
||||
user,
|
||||
externalProvider,
|
||||
stream,
|
||||
workflowStreamResponse,
|
||||
params: { temperature, maxToken, aiChatVision }
|
||||
@@ -221,7 +221,7 @@ export const runToolWithFunctionCall = async (
|
||||
getEmptyResponseTip
|
||||
} = await createChatCompletion({
|
||||
body: requestBody,
|
||||
userKey: user.openaiAccount,
|
||||
userKey: externalProvider.openaiAccount,
|
||||
options: {
|
||||
headers: {
|
||||
Accept: 'application/json, text/plain, */*'
|
||||
|
@@ -46,7 +46,7 @@ export const dispatchRunTools = async (props: DispatchToolModuleProps): Promise<
|
||||
requestOrigin,
|
||||
chatConfig,
|
||||
runningAppInfo: { teamId },
|
||||
user,
|
||||
externalProvider,
|
||||
params: {
|
||||
model,
|
||||
systemPrompt,
|
||||
@@ -153,7 +153,7 @@ export const dispatchRunTools = async (props: DispatchToolModuleProps): Promise<
|
||||
})();
|
||||
|
||||
// censor model and system key
|
||||
if (toolModel.censor && !user.openaiAccount?.key) {
|
||||
if (toolModel.censor && !externalProvider.openaiAccount?.key) {
|
||||
await postTextCensor({
|
||||
text: `${systemPrompt}
|
||||
${userChatInput}
|
||||
@@ -228,7 +228,7 @@ export const dispatchRunTools = async (props: DispatchToolModuleProps): Promise<
|
||||
tokens: toolNodeTokens,
|
||||
modelType: ModelTypeEnum.llm
|
||||
});
|
||||
const toolAIUsage = user.openaiAccount?.key ? 0 : totalPoints;
|
||||
const toolAIUsage = externalProvider.openaiAccount?.key ? 0 : totalPoints;
|
||||
|
||||
// flat child tool response
|
||||
const childToolResponse = dispatchFlowResponse.map((item) => item.flowResponses).flat();
|
||||
|
@@ -51,7 +51,7 @@ export const runToolWithPromptCall = async (
|
||||
requestOrigin,
|
||||
runtimeNodes,
|
||||
runtimeEdges,
|
||||
user,
|
||||
externalProvider,
|
||||
stream,
|
||||
workflowStreamResponse,
|
||||
params: { temperature, maxToken, aiChatVision }
|
||||
@@ -230,7 +230,7 @@ export const runToolWithPromptCall = async (
|
||||
getEmptyResponseTip
|
||||
} = await createChatCompletion({
|
||||
body: requestBody,
|
||||
userKey: user.openaiAccount,
|
||||
userKey: externalProvider.openaiAccount,
|
||||
options: {
|
||||
headers: {
|
||||
Accept: 'application/json, text/plain, */*'
|
||||
|
@@ -24,11 +24,9 @@ import { AIChatItemType } from '@fastgpt/global/core/chat/type';
|
||||
import { formatToolResponse, initToolCallEdges, initToolNodes } from './utils';
|
||||
import { computedMaxToken, llmCompletionsBodyFormat } from '../../../../ai/utils';
|
||||
import { getNanoid, sliceStrStartEnd } from '@fastgpt/global/common/string/tools';
|
||||
import { addLog } from '../../../../../common/system/log';
|
||||
import { toolValueTypeList } from '@fastgpt/global/core/workflow/constants';
|
||||
import { WorkflowInteractiveResponseType } from '@fastgpt/global/core/workflow/template/system/interactive/type';
|
||||
import { ChatItemValueTypeEnum } from '@fastgpt/global/core/chat/constants';
|
||||
import { i18nT } from '../../../../../../web/i18n/utils';
|
||||
|
||||
type ToolRunResponseType = {
|
||||
toolRunResponse: DispatchFlowResponse;
|
||||
@@ -92,7 +90,7 @@ export const runToolWithToolChoice = async (
|
||||
runtimeNodes,
|
||||
runtimeEdges,
|
||||
stream,
|
||||
user,
|
||||
externalProvider,
|
||||
workflowStreamResponse,
|
||||
params: { temperature, maxToken, aiChatVision }
|
||||
} = workflowProps;
|
||||
@@ -278,7 +276,7 @@ export const runToolWithToolChoice = async (
|
||||
getEmptyResponseTip
|
||||
} = await createChatCompletion({
|
||||
body: requestBody,
|
||||
userKey: user.openaiAccount,
|
||||
userKey: externalProvider.openaiAccount,
|
||||
options: {
|
||||
headers: {
|
||||
Accept: 'application/json, text/plain, */*'
|
||||
|
@@ -62,7 +62,7 @@ export const dispatchChatCompletion = async (props: ChatProps): Promise<ChatResp
|
||||
res,
|
||||
requestOrigin,
|
||||
stream = false,
|
||||
user,
|
||||
externalProvider,
|
||||
histories,
|
||||
node: { name },
|
||||
query,
|
||||
@@ -134,7 +134,7 @@ export const dispatchChatCompletion = async (props: ChatProps): Promise<ChatResp
|
||||
}),
|
||||
(() => {
|
||||
// censor model and system key
|
||||
if (modelConstantsData.censor && !user.openaiAccount?.key) {
|
||||
if (modelConstantsData.censor && !externalProvider.openaiAccount?.key) {
|
||||
return postTextCensor({
|
||||
text: `${systemPrompt}
|
||||
${userChatInput}
|
||||
@@ -170,7 +170,7 @@ export const dispatchChatCompletion = async (props: ChatProps): Promise<ChatResp
|
||||
// console.log(JSON.stringify(requestBody, null, 2), '===');
|
||||
const { response, isStreamResponse, getEmptyResponseTip } = await createChatCompletion({
|
||||
body: requestBody,
|
||||
userKey: user.openaiAccount,
|
||||
userKey: externalProvider.openaiAccount,
|
||||
options: {
|
||||
headers: {
|
||||
Accept: 'application/json, text/plain, */*'
|
||||
@@ -230,7 +230,7 @@ export const dispatchChatCompletion = async (props: ChatProps): Promise<ChatResp
|
||||
return {
|
||||
answerText,
|
||||
[DispatchNodeResponseKeyEnum.nodeResponse]: {
|
||||
totalPoints: user.openaiAccount?.key ? 0 : totalPoints,
|
||||
totalPoints: externalProvider.openaiAccount?.key ? 0 : totalPoints,
|
||||
model: modelName,
|
||||
tokens,
|
||||
query: `${userChatInput}`,
|
||||
@@ -245,7 +245,7 @@ export const dispatchChatCompletion = async (props: ChatProps): Promise<ChatResp
|
||||
[DispatchNodeResponseKeyEnum.nodeDispatchUsages]: [
|
||||
{
|
||||
moduleName: name,
|
||||
totalPoints: user.openaiAccount?.key ? 0 : totalPoints,
|
||||
totalPoints: externalProvider.openaiAccount?.key ? 0 : totalPoints,
|
||||
model: modelName,
|
||||
tokens
|
||||
}
|
||||
|
@@ -126,7 +126,8 @@ export async function dispatchWorkFlow(data: Props): Promise<DispatchFlowRespons
|
||||
runtimeEdges = [],
|
||||
histories = [],
|
||||
variables = {},
|
||||
user,
|
||||
timezone,
|
||||
externalProvider,
|
||||
stream = false,
|
||||
...props
|
||||
} = data;
|
||||
@@ -150,7 +151,7 @@ export async function dispatchWorkFlow(data: Props): Promise<DispatchFlowRespons
|
||||
[DispatchNodeResponseKeyEnum.runTimes]: 1,
|
||||
[DispatchNodeResponseKeyEnum.assistantResponses]: [],
|
||||
[DispatchNodeResponseKeyEnum.toolResponses]: null,
|
||||
newVariables: removeSystemVariable(variables)
|
||||
newVariables: removeSystemVariable(variables, externalProvider.externalWorkflowVariables)
|
||||
};
|
||||
}
|
||||
|
||||
@@ -180,6 +181,7 @@ export async function dispatchWorkFlow(data: Props): Promise<DispatchFlowRespons
|
||||
|
||||
variables = {
|
||||
...getSystemVariable(data),
|
||||
...externalProvider.externalWorkflowVariables,
|
||||
...variables
|
||||
};
|
||||
|
||||
@@ -493,11 +495,11 @@ export async function dispatchWorkFlow(data: Props): Promise<DispatchFlowRespons
|
||||
}
|
||||
|
||||
// replace {{xx}} variables
|
||||
let value = replaceVariable(input.value, variables);
|
||||
// let value = replaceVariable(input.value, variables);
|
||||
|
||||
// replace {{$xx.xx$}} variables
|
||||
value = replaceEditorVariable({
|
||||
text: value,
|
||||
let value = replaceEditorVariable({
|
||||
text: input.value,
|
||||
nodes: runtimeNodes,
|
||||
variables
|
||||
});
|
||||
@@ -543,7 +545,8 @@ export async function dispatchWorkFlow(data: Props): Promise<DispatchFlowRespons
|
||||
res,
|
||||
variables,
|
||||
histories,
|
||||
user,
|
||||
timezone,
|
||||
externalProvider,
|
||||
stream,
|
||||
node,
|
||||
runtimeNodes,
|
||||
@@ -677,7 +680,7 @@ export async function dispatchWorkFlow(data: Props): Promise<DispatchFlowRespons
|
||||
[DispatchNodeResponseKeyEnum.assistantResponses]:
|
||||
mergeAssistantResponseAnswerText(chatAssistantResponse),
|
||||
[DispatchNodeResponseKeyEnum.toolResponses]: toolRunResponse,
|
||||
newVariables: removeSystemVariable(variables)
|
||||
newVariables: removeSystemVariable(variables, externalProvider.externalWorkflowVariables)
|
||||
};
|
||||
} catch (error) {
|
||||
return Promise.reject(error);
|
||||
@@ -686,7 +689,7 @@ export async function dispatchWorkFlow(data: Props): Promise<DispatchFlowRespons
|
||||
|
||||
/* get system variable */
|
||||
const getSystemVariable = ({
|
||||
user,
|
||||
timezone,
|
||||
runningAppInfo,
|
||||
chatId,
|
||||
responseChatItemId,
|
||||
@@ -707,7 +710,7 @@ const getSystemVariable = ({
|
||||
chatId,
|
||||
responseChatItemId,
|
||||
histories,
|
||||
cTime: getSystemTime(user.timezone)
|
||||
cTime: getSystemTime(timezone)
|
||||
};
|
||||
};
|
||||
|
||||
|
@@ -22,7 +22,6 @@ export const dispatchLoop = async (props: Props): Promise<Response> => {
|
||||
params,
|
||||
runtimeEdges,
|
||||
runtimeNodes,
|
||||
user,
|
||||
node: { name }
|
||||
} = props;
|
||||
const { loopInputArray = [], childrenNodeIdList = [] } = params;
|
||||
@@ -86,14 +85,14 @@ export const dispatchLoop = async (props: Props): Promise<Response> => {
|
||||
return {
|
||||
[DispatchNodeResponseKeyEnum.assistantResponses]: assistantResponses,
|
||||
[DispatchNodeResponseKeyEnum.nodeResponse]: {
|
||||
totalPoints: totalPoints,
|
||||
totalPoints,
|
||||
loopInput: loopInputArray,
|
||||
loopResult: outputValueArr,
|
||||
loopDetail: loopDetail
|
||||
},
|
||||
[DispatchNodeResponseKeyEnum.nodeDispatchUsages]: [
|
||||
{
|
||||
totalPoints: user.openaiAccount?.key ? 0 : totalPoints,
|
||||
totalPoints,
|
||||
moduleName: name
|
||||
}
|
||||
],
|
||||
|
@@ -53,8 +53,8 @@ function checkCondition(condition: VariableConditionEnum, inputValue: any, value
|
||||
[VariableConditionEnum.isEmpty]: () => isEmpty(inputValue),
|
||||
[VariableConditionEnum.isNotEmpty]: () => !isEmpty(inputValue),
|
||||
|
||||
[VariableConditionEnum.equalTo]: () => String(inputValue) === value,
|
||||
[VariableConditionEnum.notEqual]: () => String(inputValue) !== value,
|
||||
[VariableConditionEnum.equalTo]: () => String(inputValue).trim() === value.trim(),
|
||||
[VariableConditionEnum.notEqual]: () => String(inputValue).trim() !== value.trim(),
|
||||
|
||||
// number
|
||||
[VariableConditionEnum.greaterThan]: () => Number(inputValue) > Number(value),
|
||||
@@ -67,8 +67,8 @@ function checkCondition(condition: VariableConditionEnum, inputValue: any, value
|
||||
[VariableConditionEnum.notInclude]: () => !isInclude(inputValue, value),
|
||||
|
||||
// string
|
||||
[VariableConditionEnum.startWith]: () => inputValue?.startsWith(value),
|
||||
[VariableConditionEnum.endWith]: () => inputValue?.endsWith(value),
|
||||
[VariableConditionEnum.startWith]: () => inputValue?.trim()?.startsWith(value),
|
||||
[VariableConditionEnum.endWith]: () => inputValue?.trim()?.endsWith(value),
|
||||
[VariableConditionEnum.reg]: () => {
|
||||
if (typeof inputValue !== 'string' || !value) return false;
|
||||
if (value.startsWith('/')) {
|
||||
@@ -79,7 +79,7 @@ function checkCondition(condition: VariableConditionEnum, inputValue: any, value
|
||||
}
|
||||
|
||||
const reg = new RegExp(value, 'g');
|
||||
const result = reg.test(inputValue);
|
||||
const result = reg.test(inputValue.trim());
|
||||
|
||||
return result;
|
||||
},
|
||||
|
@@ -19,7 +19,7 @@ type Props = ModuleDispatchProps<{
|
||||
type Response = DispatchNodeResultType<{}>;
|
||||
|
||||
export const dispatchUpdateVariable = async (props: Props): Promise<Response> => {
|
||||
const { params, variables, runtimeNodes, workflowStreamResponse, node } = props;
|
||||
const { params, variables, runtimeNodes, workflowStreamResponse, externalProvider } = props;
|
||||
|
||||
const { updateList } = params;
|
||||
const nodeIds = runtimeNodes.map((node) => node.nodeId);
|
||||
@@ -41,15 +41,15 @@ export const dispatchUpdateVariable = async (props: Props): Promise<Response> =>
|
||||
const value = (() => {
|
||||
// If first item is empty, it means it is a input value
|
||||
if (!item.value?.[0]) {
|
||||
const formatValue = valueTypeFormat(item.value?.[1], item.valueType);
|
||||
|
||||
return typeof formatValue === 'string'
|
||||
? replaceEditorVariable({
|
||||
text: formatValue,
|
||||
nodes: runtimeNodes,
|
||||
variables
|
||||
})
|
||||
: formatValue;
|
||||
const val =
|
||||
typeof item.value?.[1] === 'string'
|
||||
? replaceEditorVariable({
|
||||
text: item.value?.[1],
|
||||
nodes: runtimeNodes,
|
||||
variables
|
||||
})
|
||||
: item.value?.[1];
|
||||
return valueTypeFormat(val, item.valueType);
|
||||
} else {
|
||||
return getReferenceVariableValue({
|
||||
value: item.value,
|
||||
@@ -80,7 +80,7 @@ export const dispatchUpdateVariable = async (props: Props): Promise<Response> =>
|
||||
|
||||
workflowStreamResponse?.({
|
||||
event: SseResponseEventEnum.updateVariables,
|
||||
data: removeSystemVariable(variables)
|
||||
data: removeSystemVariable(variables, externalProvider.externalWorkflowVariables)
|
||||
});
|
||||
|
||||
return {
|
||||
|
@@ -14,6 +14,7 @@ import { NextApiResponse } from 'next';
|
||||
import { SseResponseEventEnum } from '@fastgpt/global/core/workflow/runtime/constants';
|
||||
import { getNanoid } from '@fastgpt/global/common/string/tools';
|
||||
import { SearchDataResponseItemType } from '@fastgpt/global/core/dataset/type';
|
||||
import json5 from 'json5';
|
||||
|
||||
export const getWorkflowResponseWrite = ({
|
||||
res,
|
||||
@@ -116,11 +117,18 @@ export const valueTypeFormat = (value: any, type?: WorkflowIOValueTypeEnum) => {
|
||||
return Boolean(value);
|
||||
}
|
||||
try {
|
||||
if (type === WorkflowIOValueTypeEnum.datasetQuote && !Array.isArray(value)) {
|
||||
return JSON.parse(value);
|
||||
}
|
||||
if (type === WorkflowIOValueTypeEnum.selectDataset && !Array.isArray(value)) {
|
||||
return JSON.parse(value);
|
||||
if (
|
||||
type &&
|
||||
[
|
||||
WorkflowIOValueTypeEnum.object,
|
||||
WorkflowIOValueTypeEnum.chatHistory,
|
||||
WorkflowIOValueTypeEnum.datasetQuote,
|
||||
WorkflowIOValueTypeEnum.selectApp,
|
||||
WorkflowIOValueTypeEnum.selectDataset
|
||||
].includes(type) &&
|
||||
typeof value !== 'object'
|
||||
) {
|
||||
return json5.parse(value);
|
||||
}
|
||||
} catch (error) {
|
||||
return value;
|
||||
@@ -141,14 +149,23 @@ export const checkQuoteQAValue = (quoteQA?: SearchDataResponseItemType[]) => {
|
||||
};
|
||||
|
||||
/* remove system variable */
|
||||
export const removeSystemVariable = (variables: Record<string, any>) => {
|
||||
export const removeSystemVariable = (
|
||||
variables: Record<string, any>,
|
||||
removeObj: Record<string, string> = {}
|
||||
) => {
|
||||
const copyVariables = { ...variables };
|
||||
delete copyVariables.userId;
|
||||
delete copyVariables.appId;
|
||||
delete copyVariables.chatId;
|
||||
delete copyVariables.responseChatItemId;
|
||||
delete copyVariables.histories;
|
||||
delete copyVariables.cTime;
|
||||
|
||||
// delete external provider workflow variables
|
||||
Object.keys(removeObj).forEach((key) => {
|
||||
delete copyVariables[key];
|
||||
});
|
||||
|
||||
return copyVariables;
|
||||
};
|
||||
export const filterSystemVariables = (variables: Record<string, any>): SystemVariablesType => {
|
||||
|
@@ -83,6 +83,13 @@ const OutLinkSchema = new Schema({
|
||||
}
|
||||
});
|
||||
|
||||
OutLinkSchema.virtual('associatedApp', {
|
||||
ref: AppCollectionName,
|
||||
localField: 'appId',
|
||||
foreignField: '_id',
|
||||
justOne: true
|
||||
});
|
||||
|
||||
try {
|
||||
OutLinkSchema.index({ shareId: -1 });
|
||||
} catch (error) {
|
||||
|
@@ -1,18 +1,32 @@
|
||||
import { TeamMemberWithUserSchema } from '@fastgpt/global/support/user/team/type';
|
||||
import { MongoTeamMember } from '../../user/team/teamMemberSchema';
|
||||
import { checkTeamAIPoints } from '../teamLimit';
|
||||
import { UserErrEnum } from '@fastgpt/global/common/error/code/user';
|
||||
import { UserModelSchema } from '@fastgpt/global/support/user/type';
|
||||
import { TeamSchema } from '@fastgpt/global/support/user/team/type';
|
||||
|
||||
export async function getUserChatInfoAndAuthTeamPoints(tmbId: string) {
|
||||
const tmb = (await MongoTeamMember.findById(tmbId, 'teamId userId').populate(
|
||||
'userId',
|
||||
'timezone openaiAccount'
|
||||
)) as TeamMemberWithUserSchema;
|
||||
const tmb = await MongoTeamMember.findById(tmbId, 'userId teamId')
|
||||
.populate<{ user: UserModelSchema; team: TeamSchema }>([
|
||||
{
|
||||
path: 'user',
|
||||
select: 'timezone'
|
||||
},
|
||||
{
|
||||
path: 'team',
|
||||
select: 'openaiAccount externalWorkflowVariables'
|
||||
}
|
||||
])
|
||||
.lean();
|
||||
|
||||
if (!tmb) return Promise.reject(UserErrEnum.unAuthUser);
|
||||
|
||||
await checkTeamAIPoints(tmb.teamId);
|
||||
await checkTeamAIPoints(tmb.team._id);
|
||||
|
||||
return {
|
||||
user: tmb.userId
|
||||
timezone: tmb.user.timezone,
|
||||
externalProvider: {
|
||||
openaiAccount: tmb.team.openaiAccount,
|
||||
externalWorkflowVariables: tmb.team.externalWorkflowVariables
|
||||
}
|
||||
};
|
||||
}
|
||||
|
@@ -10,17 +10,17 @@ import { MongoResourcePermission } from './schema';
|
||||
import { ClientSession } from 'mongoose';
|
||||
import {
|
||||
PermissionValueType,
|
||||
ResourcePermissionType,
|
||||
ResourcePerWithGroup,
|
||||
ResourcePerWithTmbWithUser
|
||||
ResourcePermissionType
|
||||
} from '@fastgpt/global/support/permission/type';
|
||||
import { bucketNameMap } from '@fastgpt/global/common/file/constants';
|
||||
import { addMinutes } from 'date-fns';
|
||||
import { getGroupsByTmbId } from './memberGroup/controllers';
|
||||
import { Permission } from '@fastgpt/global/support/permission/controller';
|
||||
import { ParentIdType } from '@fastgpt/global/common/parentFolder/type';
|
||||
import { RequireOnlyOne } from '@fastgpt/global/common/type/utils';
|
||||
import { CommonErrEnum } from '@fastgpt/global/common/error/code/common';
|
||||
import { MemberGroupSchemaType } from '@fastgpt/global/support/permission/memberGroup/type';
|
||||
import { TeamMemberSchema } from '@fastgpt/global/support/user/team/type';
|
||||
import { UserModelSchema } from '@fastgpt/global/support/user/type';
|
||||
|
||||
/** get resource permission for a team member
|
||||
* If there is no permission for the team member, it will return undefined
|
||||
@@ -160,32 +160,33 @@ export const getClbsAndGroupsWithInfo = async ({
|
||||
teamId: string;
|
||||
}) =>
|
||||
Promise.all([
|
||||
(await MongoResourcePermission.find({
|
||||
MongoResourcePermission.find({
|
||||
teamId,
|
||||
resourceId,
|
||||
resourceType,
|
||||
tmbId: {
|
||||
$exists: true
|
||||
}
|
||||
}).populate({
|
||||
path: 'tmbId',
|
||||
select: 'name userId',
|
||||
populate: {
|
||||
path: 'userId',
|
||||
select: 'avatar'
|
||||
}
|
||||
})) as ResourcePerWithTmbWithUser[],
|
||||
(await MongoResourcePermission.find({
|
||||
})
|
||||
.populate<{ tmb: TeamMemberSchema & { user: UserModelSchema } }>({
|
||||
path: 'tmb',
|
||||
select: 'name userId',
|
||||
populate: {
|
||||
path: 'user',
|
||||
select: 'avatar'
|
||||
}
|
||||
})
|
||||
.lean(),
|
||||
MongoResourcePermission.find({
|
||||
teamId,
|
||||
resourceId,
|
||||
resourceType,
|
||||
groupId: {
|
||||
$exists: true
|
||||
}
|
||||
}).populate({
|
||||
path: 'groupId',
|
||||
select: 'name avatar'
|
||||
})) as ResourcePerWithGroup[]
|
||||
})
|
||||
.populate<{ group: MemberGroupSchemaType }>('group', 'name avatar')
|
||||
.lean()
|
||||
]);
|
||||
|
||||
export const delResourcePermissionById = (id: string) => {
|
||||
|
@@ -3,7 +3,6 @@ import { getResourcePermission, parseHeaderCert } from '../controller';
|
||||
import {
|
||||
CollectionWithDatasetType,
|
||||
DatasetDataItemType,
|
||||
DatasetFileSchema,
|
||||
DatasetSchemaType
|
||||
} from '@fastgpt/global/core/dataset/type';
|
||||
import { getTmbInfoByTmbId } from '../../user/team/controller';
|
||||
@@ -12,10 +11,6 @@ import { NullPermission, PerResourceTypeEnum } from '@fastgpt/global/support/per
|
||||
import { DatasetErrEnum } from '@fastgpt/global/common/error/code/dataset';
|
||||
import { DatasetPermission } from '@fastgpt/global/support/permission/dataset/controller';
|
||||
import { getCollectionWithDataset } from '../../../core/dataset/controller';
|
||||
import { MongoDatasetCollection } from '../../../core/dataset/collection/schema';
|
||||
import { getFileById } from '../../../common/file/gridfs/controller';
|
||||
import { BucketNameEnum } from '@fastgpt/global/common/file/constants';
|
||||
import { CommonErrEnum } from '@fastgpt/global/common/error/code/common';
|
||||
import { MongoDatasetData } from '../../../core/dataset/data/schema';
|
||||
import { AuthModeType, AuthResponseType } from '../type';
|
||||
import { DatasetTypeEnum } from '@fastgpt/global/core/dataset/constants';
|
||||
@@ -181,7 +176,7 @@ export async function authDatasetCollection({
|
||||
|
||||
const { dataset } = await authDatasetByTmbId({
|
||||
tmbId,
|
||||
datasetId: collection.datasetId._id,
|
||||
datasetId: collection.datasetId,
|
||||
per,
|
||||
isRoot: isRootFromHeader
|
||||
});
|
||||
|
@@ -66,48 +66,19 @@ export const getGroupsByTmbId = async ({
|
||||
},
|
||||
...(role ? { role: { $in: role } } : {})
|
||||
})
|
||||
.populate('groupId')
|
||||
.populate<{ group: MemberGroupSchemaType }>('group')
|
||||
.lean()
|
||||
).map((item) => {
|
||||
return {
|
||||
...(item.groupId as any as MemberGroupSchemaType)
|
||||
};
|
||||
}),
|
||||
|
||||
).map((item) => item.group),
|
||||
role ? [] : getTeamDefaultGroup({ teamId })
|
||||
])
|
||||
).flat();
|
||||
|
||||
export const getTmbByGroupId = async (groupId: string) => {
|
||||
return (
|
||||
await MongoGroupMemberModel.find({
|
||||
groupId
|
||||
})
|
||||
.populate('tmbId')
|
||||
.lean()
|
||||
).map((item) => {
|
||||
return {
|
||||
...(item.tmbId as any as MemberGroupSchemaType)
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
export const getGroupMembersByGroupId = async (groupId: string) => {
|
||||
return await MongoGroupMemberModel.find({
|
||||
groupId
|
||||
}).lean();
|
||||
};
|
||||
|
||||
export const getGroupMembersWithInfoByGroupId = async (groupId: string) => {
|
||||
return (
|
||||
await MongoGroupMemberModel.find({
|
||||
groupId
|
||||
})
|
||||
.populate('tmbId')
|
||||
.lean()
|
||||
).map((item) => item.tmbId) as any as TeamMemberSchema[]; // HACK: type casting
|
||||
};
|
||||
|
||||
/**
|
||||
* Get tmb's group permission: the maximum permission of the group
|
||||
* @param tmbId
|
||||
|
@@ -26,6 +26,13 @@ export const GroupMemberSchema = new Schema({
|
||||
}
|
||||
});
|
||||
|
||||
GroupMemberSchema.virtual('group', {
|
||||
ref: MemberGroupCollectionName,
|
||||
localField: 'groupId',
|
||||
foreignField: '_id',
|
||||
justOne: true
|
||||
});
|
||||
|
||||
try {
|
||||
GroupMemberSchema.index({
|
||||
groupId: 1
|
||||
|
@@ -39,6 +39,19 @@ export const ResourcePermissionSchema = new Schema({
|
||||
}
|
||||
});
|
||||
|
||||
ResourcePermissionSchema.virtual('tmb', {
|
||||
ref: TeamMemberCollectionName,
|
||||
localField: 'tmbId',
|
||||
foreignField: '_id',
|
||||
justOne: true
|
||||
});
|
||||
ResourcePermissionSchema.virtual('group', {
|
||||
ref: MemberGroupCollectionName,
|
||||
localField: 'groupId',
|
||||
foreignField: '_id',
|
||||
justOne: true
|
||||
});
|
||||
|
||||
try {
|
||||
ResourcePermissionSchema.index(
|
||||
{
|
||||
|
@@ -44,7 +44,6 @@ export async function getUserDetail({
|
||||
avatar: user.avatar,
|
||||
timezone: user.timezone,
|
||||
promotionRate: user.promotionRate,
|
||||
openaiAccount: user.openaiAccount,
|
||||
team: tmb,
|
||||
notificationAccount: tmb.notificationAccount,
|
||||
permission: tmb.permission
|
||||
|
@@ -1,4 +1,4 @@
|
||||
import { TeamTmbItemType, TeamMemberWithTeamSchema } from '@fastgpt/global/support/user/team/type';
|
||||
import { TeamSchema, TeamTmbItemType } from '@fastgpt/global/support/user/team/type';
|
||||
import { ClientSession, Types } from '../../../common/mongo';
|
||||
import {
|
||||
TeamMemberRoleEnum,
|
||||
@@ -15,37 +15,41 @@ import { TeamDefaultPermissionVal } from '@fastgpt/global/support/permission/use
|
||||
import { MongoMemberGroupModel } from '../../permission/memberGroup/memberGroupSchema';
|
||||
import { mongoSessionRun } from '../../../common/mongo/sessionRun';
|
||||
import { DefaultGroupName } from '@fastgpt/global/support/user/team/group/constant';
|
||||
import { getAIApi, openaiBaseUrl } from '../../../core/ai/config';
|
||||
|
||||
async function getTeamMember(match: Record<string, any>): Promise<TeamTmbItemType> {
|
||||
const tmb = (await MongoTeamMember.findOne(match).populate('teamId')) as TeamMemberWithTeamSchema;
|
||||
const tmb = await MongoTeamMember.findOne(match).populate<{ team: TeamSchema }>('team').lean();
|
||||
if (!tmb) {
|
||||
return Promise.reject('member not exist');
|
||||
}
|
||||
|
||||
const Per = await getResourcePermission({
|
||||
resourceType: PerResourceTypeEnum.team,
|
||||
teamId: tmb.teamId._id,
|
||||
teamId: tmb.teamId,
|
||||
tmbId: tmb._id
|
||||
});
|
||||
|
||||
return {
|
||||
userId: String(tmb.userId),
|
||||
teamId: String(tmb.teamId._id),
|
||||
teamName: tmb.teamId.name,
|
||||
teamId: String(tmb.teamId),
|
||||
teamName: tmb.team.name,
|
||||
memberName: tmb.name,
|
||||
avatar: tmb.teamId.avatar,
|
||||
balance: tmb.teamId.balance,
|
||||
avatar: tmb.team.avatar,
|
||||
balance: tmb.team.balance,
|
||||
tmbId: String(tmb._id),
|
||||
teamDomain: tmb.teamId?.teamDomain,
|
||||
teamDomain: tmb.team?.teamDomain,
|
||||
role: tmb.role,
|
||||
status: tmb.status,
|
||||
defaultTeam: tmb.defaultTeam,
|
||||
lafAccount: tmb.teamId.lafAccount,
|
||||
permission: new TeamPermission({
|
||||
per: Per ?? TeamDefaultPermissionVal,
|
||||
isOwner: tmb.role === TeamMemberRoleEnum.owner
|
||||
}),
|
||||
notificationAccount: tmb.teamId.notificationAccount
|
||||
notificationAccount: tmb.team.notificationAccount,
|
||||
|
||||
lafAccount: tmb.team.lafAccount,
|
||||
openaiAccount: tmb.team.openaiAccount,
|
||||
externalWorkflowVariables: tmb.team.externalWorkflowVariables
|
||||
};
|
||||
}
|
||||
|
||||
@@ -145,21 +149,87 @@ export async function updateTeam({
|
||||
name,
|
||||
avatar,
|
||||
teamDomain,
|
||||
lafAccount
|
||||
lafAccount,
|
||||
openaiAccount,
|
||||
externalWorkflowVariable
|
||||
}: UpdateTeamProps & { teamId: string }) {
|
||||
// auth openai key
|
||||
if (openaiAccount?.key) {
|
||||
console.log('auth user openai key', openaiAccount?.key);
|
||||
const baseUrl = openaiAccount?.baseUrl || openaiBaseUrl;
|
||||
openaiAccount.baseUrl = baseUrl;
|
||||
|
||||
const ai = getAIApi({
|
||||
userKey: openaiAccount
|
||||
});
|
||||
|
||||
const response = await ai.chat.completions.create({
|
||||
model: 'gpt-4o-mini',
|
||||
max_tokens: 1,
|
||||
messages: [{ role: 'user', content: 'hi' }]
|
||||
});
|
||||
if (response?.choices?.[0]?.message?.content === undefined) {
|
||||
return Promise.reject('Key response is empty');
|
||||
}
|
||||
}
|
||||
|
||||
return mongoSessionRun(async (session) => {
|
||||
const unsetObj = (() => {
|
||||
const obj: Record<string, 1> = {};
|
||||
if (lafAccount?.pat === '') {
|
||||
obj.lafAccount = 1;
|
||||
}
|
||||
if (openaiAccount?.key === '') {
|
||||
obj.openaiAccount = 1;
|
||||
}
|
||||
if (externalWorkflowVariable) {
|
||||
if (externalWorkflowVariable.value === '') {
|
||||
obj[`externalWorkflowVariables.${externalWorkflowVariable.key}`] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (Object.keys(obj).length === 0) {
|
||||
return undefined;
|
||||
}
|
||||
return {
|
||||
$unset: obj
|
||||
};
|
||||
})();
|
||||
const setObj = (() => {
|
||||
const obj: Record<string, any> = {};
|
||||
if (lafAccount?.pat && lafAccount?.appid) {
|
||||
obj.lafAccount = lafAccount;
|
||||
}
|
||||
if (openaiAccount?.key && openaiAccount?.baseUrl) {
|
||||
obj.openaiAccount = openaiAccount;
|
||||
}
|
||||
if (externalWorkflowVariable) {
|
||||
if (externalWorkflowVariable.value !== '') {
|
||||
obj[`externalWorkflowVariables.${externalWorkflowVariable.key}`] =
|
||||
externalWorkflowVariable.value;
|
||||
}
|
||||
}
|
||||
if (Object.keys(obj).length === 0) {
|
||||
return undefined;
|
||||
}
|
||||
return obj;
|
||||
})();
|
||||
|
||||
await MongoTeam.findByIdAndUpdate(
|
||||
teamId,
|
||||
{
|
||||
name,
|
||||
avatar,
|
||||
teamDomain,
|
||||
lafAccount
|
||||
$set: {
|
||||
...(name ? { name } : {}),
|
||||
...(avatar ? { avatar } : {}),
|
||||
...(teamDomain ? { teamDomain } : {}),
|
||||
...setObj
|
||||
},
|
||||
...unsetObj
|
||||
},
|
||||
{ session }
|
||||
);
|
||||
|
||||
// update default group
|
||||
// Update member group avatar
|
||||
if (avatar) {
|
||||
await MongoMemberGroupModel.updateOne(
|
||||
{
|
||||
|
@@ -3,7 +3,6 @@ const { Schema } = connectionMongo;
|
||||
import { TeamMemberSchema as TeamMemberType } from '@fastgpt/global/support/user/team/type.d';
|
||||
import { userCollectionName } from '../../user/schema';
|
||||
import {
|
||||
TeamMemberRoleMap,
|
||||
TeamMemberStatusMap,
|
||||
TeamMemberCollectionName,
|
||||
TeamCollectionName
|
||||
@@ -42,6 +41,19 @@ const TeamMemberSchema = new Schema({
|
||||
}
|
||||
});
|
||||
|
||||
TeamMemberSchema.virtual('team', {
|
||||
ref: TeamCollectionName,
|
||||
localField: 'teamId',
|
||||
foreignField: '_id',
|
||||
justOne: true
|
||||
});
|
||||
TeamMemberSchema.virtual('user', {
|
||||
ref: userCollectionName,
|
||||
localField: 'userId',
|
||||
foreignField: '_id',
|
||||
justOne: true
|
||||
});
|
||||
|
||||
try {
|
||||
TeamMemberSchema.index({ teamId: 1 }, { background: true });
|
||||
TeamMemberSchema.index({ userId: 1 }, { background: true });
|
||||
|
@@ -47,6 +47,16 @@ const TeamSchema = new Schema({
|
||||
type: String
|
||||
}
|
||||
},
|
||||
openaiAccount: {
|
||||
type: {
|
||||
key: String,
|
||||
baseUrl: String
|
||||
}
|
||||
},
|
||||
externalWorkflowVariables: {
|
||||
type: Object,
|
||||
default: {}
|
||||
},
|
||||
notificationAccount: {
|
||||
type: String,
|
||||
required: false
|
||||
|
2
packages/service/type.d.ts
vendored
@@ -9,7 +9,6 @@ import {
|
||||
import { SubPlanType } from '@fastgpt/global/support/wallet/sub/type';
|
||||
import { WorkerNameEnum, WorkerPool } from './worker/utils';
|
||||
import { Worker } from 'worker_threads';
|
||||
import { TemplateMarketItemType } from '@fastgpt/global/core/workflow/type';
|
||||
|
||||
declare global {
|
||||
var systemInitBufferId: string | undefined;
|
||||
@@ -25,5 +24,4 @@ declare global {
|
||||
var reRankModels: ReRankModelItemType[];
|
||||
|
||||
var workerPoll: Record<WorkerNameEnum, WorkerPool>;
|
||||
var appMarketTemplates: TemplateMarketItemType[];
|
||||
}
|
||||
|
3
packages/templates/README.md
Normal file
@@ -0,0 +1,3 @@
|
||||
# Package 说明
|
||||
|
||||
该 package 存放应用模板。
|
10
packages/templates/package.json
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"name": "@fastgpt/templates",
|
||||
"version": "1.0.0",
|
||||
"type": "module",
|
||||
"dependencies": {},
|
||||
"devDependencies": {
|
||||
"@fastgpt/global": "workspace:*",
|
||||
"@fastgpt/service": "workspace:*"
|
||||
}
|
||||
}
|
83
packages/templates/register.ts
Normal file
@@ -0,0 +1,83 @@
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
import { isProduction } from '@fastgpt/global/common/system/constants';
|
||||
import { PluginSourceEnum } from '@fastgpt/global/core/plugin/constants';
|
||||
import { MongoAppTemplate } from '@fastgpt/service/core/app/templates/templateSchema';
|
||||
import { AppTemplateSchemaType } from '@fastgpt/global/core/app/type';
|
||||
|
||||
const getTemplateNameList = () => {
|
||||
const currentFileUrl = new URL(import.meta.url);
|
||||
const templatesPath = path.join(path.dirname(currentFileUrl.pathname), 'src');
|
||||
|
||||
return fs.readdirSync(templatesPath) as string[];
|
||||
};
|
||||
|
||||
const getFileTemplates = (): AppTemplateSchemaType[] => {
|
||||
const templateNames = getTemplateNameList();
|
||||
|
||||
const appMarketTemplates = templateNames.map((name) => {
|
||||
const fileContent = require(`./src/${name}/template.json`);
|
||||
|
||||
return {
|
||||
...fileContent,
|
||||
templateId: `${PluginSourceEnum.community}-${name}`,
|
||||
isActive: true
|
||||
};
|
||||
});
|
||||
|
||||
return appMarketTemplates;
|
||||
};
|
||||
|
||||
const getAppTemplates = async () => {
|
||||
const communityTemplates = getFileTemplates();
|
||||
|
||||
const dbTemplates = await MongoAppTemplate.find();
|
||||
|
||||
// Merge db data to community templates
|
||||
const communityTemplateConfig = communityTemplates.map((template) => {
|
||||
const config = dbTemplates.find((t) => t.templateId === template.templateId);
|
||||
|
||||
if (config) {
|
||||
return {
|
||||
...template,
|
||||
isActive: config.isActive ?? template.isActive,
|
||||
tags: config.tags ?? template.tags,
|
||||
userGuide: config.userGuide ?? template.userGuide,
|
||||
isQuickTemplate: config.isQuickTemplate ?? template.isQuickTemplate,
|
||||
order: config.order ?? template.order
|
||||
};
|
||||
}
|
||||
|
||||
return template;
|
||||
});
|
||||
|
||||
const res = [
|
||||
...communityTemplateConfig,
|
||||
...dbTemplates.filter((t) => !isCommunityTemplate(t.templateId))
|
||||
].sort((a, b) => (a.order ?? 0) - (b.order ?? 0));
|
||||
|
||||
return res;
|
||||
};
|
||||
|
||||
export const getAppTemplatesAndLoadThem = async (refresh = false) => {
|
||||
if (isProduction && global.appTemplates && global.appTemplates.length > 0 && !refresh)
|
||||
return global.appTemplates;
|
||||
|
||||
if (!global.appTemplates) {
|
||||
global.appTemplates = [];
|
||||
}
|
||||
|
||||
try {
|
||||
const appTemplates = await getAppTemplates();
|
||||
global.appTemplates = appTemplates;
|
||||
return appTemplates;
|
||||
} catch (error) {
|
||||
// @ts-ignore
|
||||
global.appTemplates = undefined;
|
||||
return [];
|
||||
}
|
||||
};
|
||||
|
||||
export const isCommunityTemplate = (templateId: string) => {
|
||||
return templateId.startsWith(PluginSourceEnum.community);
|
||||
};
|
@@ -2,9 +2,13 @@
|
||||
"name": "汉语新解",
|
||||
"intro": "生成汉语释义图",
|
||||
"author": "",
|
||||
"avatar": "/appMarketTemplates/Chinese/avatar.svg",
|
||||
"avatar": "core/app/templates/chinese",
|
||||
"tags": ["roleplay"],
|
||||
"type": "advanced",
|
||||
"userGuide": {
|
||||
"type": "link",
|
||||
"content": "https://mp.weixin.qq.com/s/T90-uZqGovYR90fST0o80Q"
|
||||
},
|
||||
"workflow": {
|
||||
"nodes": [
|
||||
{
|
@@ -2,7 +2,7 @@
|
||||
"name": "多轮翻译机器人",
|
||||
"intro": "通过 4 轮翻译,提高翻译英文的质量",
|
||||
"author": "",
|
||||
"avatar": "/appMarketTemplates/TranslateRobot/avatar.svg",
|
||||
"avatar": "core/app/templates/TranslateRobot",
|
||||
"tags": ["office-services"],
|
||||
"type": "advanced",
|
||||
"workflow": {
|
@@ -2,7 +2,7 @@
|
||||
"name": "动物的一生",
|
||||
"intro": "使用AI生成任何事物的 “人生图”",
|
||||
"author": "",
|
||||
"avatar": "/appMarketTemplates/animalLife/avatar.svg",
|
||||
"avatar": "core/app/templates/animalLife",
|
||||
"tags": ["roleplay"],
|
||||
"type": "advanced",
|
||||
"workflow": {
|
@@ -2,7 +2,7 @@
|
||||
"name": "周易占卜",
|
||||
"intro": "AI占卜,快来算算你的运势~",
|
||||
"author": "",
|
||||
"avatar": "/appMarketTemplates/divination/avatar.svg",
|
||||
"avatar": "core/app/templates/divination",
|
||||
"tags": ["roleplay"],
|
||||
"type": "advanced",
|
||||
"workflow": {
|
@@ -2,7 +2,7 @@
|
||||
"name": "Flux 绘图",
|
||||
"intro": "通过请求 Flux 接口绘图,需要有 api key",
|
||||
"author": "",
|
||||
"avatar": "/appMarketTemplates/flux/avatar.svg",
|
||||
"avatar": "core/app/templates/flux",
|
||||
"type": "plugin",
|
||||
"tags": ["image-generation"],
|
||||
"workflow": {
|
@@ -2,9 +2,13 @@
|
||||
"name": "GitHub Issue 总结机器人",
|
||||
"intro": "定时获取GitHub Issue信息,使用AI进行总结,并推送到飞书群中",
|
||||
"author": "",
|
||||
"avatar": "/appMarketTemplates/githubIssue/avatar.svg",
|
||||
"avatar": "core/app/templates/githubIssue",
|
||||
"tags": ["office-services"],
|
||||
"type": "advanced",
|
||||
"userGuide": {
|
||||
"type": "link",
|
||||
"content": "https://mp.weixin.qq.com/s/CBrwSn1jQZO7ybsMSx5GnQ"
|
||||
},
|
||||
"workflow": {
|
||||
"nodes": [
|
||||
{
|
@@ -2,7 +2,7 @@
|
||||
"name": "谷歌搜索",
|
||||
"intro": "通过请求谷歌搜索,查询相关内容作为模型的参考。",
|
||||
"author": "",
|
||||
"avatar": "/appMarketTemplates/google/avatar.svg",
|
||||
"avatar": "core/app/templates/google",
|
||||
"tags": ["recommendation", "web-search"],
|
||||
"type": "advanced",
|
||||
"workflow": {
|
@@ -1,10 +1,14 @@
|
||||
{
|
||||
"name": "长文翻译专家",
|
||||
"intro": "使用专有名称知识库协助翻译,更适合长文本的翻译机器人",
|
||||
"intro": "使用专有名词知识库协助翻译,更适合长文本的翻译机器人",
|
||||
"author": "",
|
||||
"avatar": "/appMarketTemplates/TranslateRobot/avatar.svg",
|
||||
"avatar": "core/app/templates/TranslateRobot",
|
||||
"tags": ["office-services"],
|
||||
"type": "advanced",
|
||||
"userGuide": {
|
||||
"type": "link",
|
||||
"content": "https://mp.weixin.qq.com/s/2kXdaSLOImhH1DTaFU8qXA"
|
||||
},
|
||||
"workflow": {
|
||||
"nodes": [
|
||||
{
|
@@ -2,7 +2,7 @@
|
||||
"name": "Dalle3 绘图",
|
||||
"intro": "通过请求 Dalle3 接口绘图,需要有 api key",
|
||||
"author": "",
|
||||
"avatar": "/appMarketTemplates/plugin-dalle/avatar.svg",
|
||||
"avatar": "core/app/templates/plugin-dalle",
|
||||
"type": "plugin",
|
||||
"tags": ["recommendation", "image-generation"],
|
||||
"workflow": {
|
@@ -2,7 +2,7 @@
|
||||
"name": "飞书 webhook 插件",
|
||||
"intro": "通过 webhook 给飞书机器人发送一条消息",
|
||||
"author": "",
|
||||
"avatar": "/appMarketTemplates/plugin-feishu/avatar.svg",
|
||||
"avatar": "core/app/templates/plugin-feishu",
|
||||
"type": "plugin",
|
||||
"tags": ["recommendation", "office-services"],
|
||||
"workflow": {
|
@@ -2,9 +2,13 @@
|
||||
"name": "长字幕反思翻译机器人",
|
||||
"intro": "利用 AI 自我反思提升翻译质量,同时循环迭代执行 AI 工作流来突破 LLM tokens 限制,实现一个高效的长字幕翻译机器人",
|
||||
"author": "",
|
||||
"avatar": "/appMarketTemplates/TranslateRobot/avatar.svg",
|
||||
"avatar": "core/app/templates/TranslateRobot",
|
||||
"tags": ["office-services"],
|
||||
"type": "advanced",
|
||||
"userGuide": {
|
||||
"type": "link",
|
||||
"content": "https://mp.weixin.qq.com/s/uztciEVvumNWNlct0IeJ-w"
|
||||
},
|
||||
"workflow": {
|
||||
"nodes": [
|
||||
{
|
@@ -2,7 +2,7 @@
|
||||
"name": "利好大A",
|
||||
"intro": "",
|
||||
"author": "",
|
||||
"avatar": "/appMarketTemplates/stock/avatar.svg",
|
||||
"avatar": "core/app/templates/stock",
|
||||
"tags": ["roleplay"],
|
||||
"type": "advanced",
|
||||
"workflow": {
|
21
packages/templates/tsconfig.json
Normal file
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "es2015",
|
||||
"lib": ["dom", "dom.iterable", "esnext"],
|
||||
"allowJs": true,
|
||||
"skipLibCheck": true,
|
||||
"strict": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"noEmit": true,
|
||||
"esModuleInterop": true,
|
||||
"module": "esnext",
|
||||
"moduleResolution": "node",
|
||||
"resolveJsonModule": true,
|
||||
"isolatedModules": true,
|
||||
"jsx": "preserve",
|
||||
"incremental": true,
|
||||
"baseUrl": "."
|
||||
},
|
||||
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", "**/*.d.ts", "../**/*.d.ts"],
|
||||
"exclude": ["node_modules"]
|
||||
}
|
5
packages/templates/type.d.ts
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
import { AppTemplateSchemaType } from '@fastgpt/global/core/app/type';
|
||||
|
||||
declare global {
|
||||
var appTemplates: AppTemplateSchemaType[];
|
||||
}
|
@@ -28,4 +28,4 @@ const Avatar = ({ w = '30px', src, ...props }: ImageProps) => {
|
||||
);
|
||||
};
|
||||
|
||||
export default Avatar;
|
||||
export default React.memo(Avatar);
|
||||
|
@@ -57,4 +57,4 @@ function DndDrag<T>({ children, renderClone, onDragEndCb, dataList }: Props<T>)
|
||||
);
|
||||
}
|
||||
|
||||
export default DndDrag;
|
||||
export default React.memo(DndDrag) as <T>(props: Props<T>) => React.ReactElement;
|
||||
|
@@ -17,6 +17,7 @@ export const iconPaths = {
|
||||
'common/addUser': () => import('./icons/common/addUser.svg'),
|
||||
'common/administrator': () => import('./icons/common/administrator.svg'),
|
||||
'common/arrowLeft': () => import('./icons/common/arrowLeft.svg'),
|
||||
'common/arrowRight': () => import('./icons/common/arrowRight.svg'),
|
||||
'common/backFill': () => import('./icons/common/backFill.svg'),
|
||||
'common/backLight': () => import('./icons/common/backLight.svg'),
|
||||
'common/billing': () => import('./icons/common/billing.svg'),
|
||||
@@ -48,6 +49,7 @@ export const iconPaths = {
|
||||
'common/language/China': () => import('./icons/common/language/China.svg'),
|
||||
'common/language/en': () => import('./icons/common/language/en.svg'),
|
||||
'common/language/zh': () => import('./icons/common/language/zh.svg'),
|
||||
'common/layer': () => import('./icons/common/layer.svg'),
|
||||
'common/leftArrowLight': () => import('./icons/common/leftArrowLight.svg'),
|
||||
'common/line': () => import('./icons/common/line.svg'),
|
||||
'common/lineChange': () => import('./icons/common/lineChange.svg'),
|
||||
@@ -81,13 +83,16 @@ export const iconPaths = {
|
||||
'common/settingLight': () => import('./icons/common/settingLight.svg'),
|
||||
'common/solidChevronRight': () => import('./icons/common/solidChevronRight.svg'),
|
||||
'common/subtract': () => import('./icons/common/subtract.svg'),
|
||||
'common/templateMarket': () => import('./icons/common/templateMarket.svg'),
|
||||
'common/text/t': () => import('./icons/common/text/t.svg'),
|
||||
'common/thirdParty': () => import('./icons/common/thirdParty.svg'),
|
||||
'common/tickFill': () => import('./icons/common/tickFill.svg'),
|
||||
'common/toolkit': () => import('./icons/common/toolkit.svg'),
|
||||
'common/trash': () => import('./icons/common/trash.svg'),
|
||||
'common/upRightArrowLight': () => import('./icons/common/upRightArrowLight.svg'),
|
||||
'common/uploadFileFill': () => import('./icons/common/uploadFileFill.svg'),
|
||||
'common/userInfo': () => import('./icons/common/userInfo.svg'),
|
||||
'common/variable': () => import('./icons/common/variable.svg'),
|
||||
'common/viewLight': () => import('./icons/common/viewLight.svg'),
|
||||
'common/voiceLight': () => import('./icons/common/voiceLight.svg'),
|
||||
'common/warn': () => import('./icons/common/warn.svg'),
|
||||
@@ -119,6 +124,17 @@ export const iconPaths = {
|
||||
'core/app/simpleMode/tts': () => import('./icons/core/app/simpleMode/tts.svg'),
|
||||
'core/app/simpleMode/variable': () => import('./icons/core/app/simpleMode/variable.svg'),
|
||||
'core/app/simpleMode/whisper': () => import('./icons/core/app/simpleMode/whisper.svg'),
|
||||
'core/app/templates/TranslateRobot': () =>
|
||||
import('./icons/core/app/templates/TranslateRobot.svg'),
|
||||
'core/app/templates/animalLife': () => import('./icons/core/app/templates/animalLife.svg'),
|
||||
'core/app/templates/chinese': () => import('./icons/core/app/templates/chinese.svg'),
|
||||
'core/app/templates/divination': () => import('./icons/core/app/templates/divination.svg'),
|
||||
'core/app/templates/flux': () => import('./icons/core/app/templates/flux.svg'),
|
||||
'core/app/templates/githubIssue': () => import('./icons/core/app/templates/githubIssue.svg'),
|
||||
'core/app/templates/google': () => import('./icons/core/app/templates/google.svg'),
|
||||
'core/app/templates/plugin-dalle': () => import('./icons/core/app/templates/plugin-dalle.svg'),
|
||||
'core/app/templates/plugin-feishu': () => import('./icons/core/app/templates/plugin-feishu.svg'),
|
||||
'core/app/templates/stock': () => import('./icons/core/app/templates/stock.svg'),
|
||||
'core/app/toolCall': () => import('./icons/core/app/toolCall.svg'),
|
||||
'core/app/ttsFill': () => import('./icons/core/app/ttsFill.svg'),
|
||||
'core/app/type/httpPlugin': () => import('./icons/core/app/type/httpPlugin.svg'),
|
||||
@@ -376,6 +392,7 @@ export const iconPaths = {
|
||||
'price/right': () => import('./icons/price/right.svg'),
|
||||
save: () => import('./icons/save.svg'),
|
||||
stop: () => import('./icons/stop.svg'),
|
||||
'support/account/laf': () => import('./icons/support/account/laf.svg'),
|
||||
'support/account/loginoutLight': () => import('./icons/support/account/loginoutLight.svg'),
|
||||
'support/account/plans': () => import('./icons/support/account/plans.svg'),
|
||||
'support/account/promotionLight': () => import('./icons/support/account/promotionLight.svg'),
|
||||
|
@@ -0,0 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="none">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M8.86193 3.5286C8.60158 3.78895 8.60158 4.21106 8.86193 4.47141L11.7239 7.33334H2.66667C2.29848 7.33334 2 7.63181 2 8C2 8.36819 2.29848 8.66667 2.66667 8.66667H11.7239L8.86193 11.5286C8.60158 11.7889 8.60158 12.2111 8.86193 12.4714C9.12228 12.7318 9.54439 12.7318 9.80474 12.4714L13.8047 8.47141C14.0651 8.21106 14.0651 7.78895 13.8047 7.5286L9.80474 3.5286C9.54439 3.26825 9.12228 3.26825 8.86193 3.5286Z"/>
|
||||
</svg>
|
After Width: | Height: | Size: 539 B |
@@ -0,0 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 18 18" fill="none">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M8.79789 1.3894C8.93146 1.36434 9.06853 1.36434 9.2021 1.3894C9.36089 1.41919 9.5023 1.49151 9.56594 1.52407C9.57246 1.5274 9.57817 1.53032 9.58299 1.53273L16.2556 4.86906C16.5097 4.9961 16.6702 5.2558 16.6702 5.53988C16.6702 5.82396 16.5097 6.08366 16.2556 6.2107L9.58299 9.54703C9.57817 9.54944 9.57246 9.55236 9.56594 9.5557C9.5023 9.58825 9.36089 9.66058 9.2021 9.69037C9.06853 9.71543 8.93146 9.71543 8.79789 9.69037C8.6391 9.66058 8.4977 9.58825 8.43405 9.5557C8.42753 9.55236 8.42182 9.54944 8.417 9.54703L1.74434 6.2107C1.49026 6.08366 1.32975 5.82396 1.32975 5.53988C1.32975 5.2558 1.49026 4.9961 1.74434 4.86906L8.417 1.53273C8.42182 1.53032 8.42753 1.5274 8.43405 1.52407C8.49769 1.49151 8.6391 1.41919 8.79789 1.3894ZM9 2.91829L3.7568 5.53988L9 8.16148L14.2432 5.53988L9 2.91829ZM1.40893 8.66459C1.59418 8.29411 2.04468 8.14394 2.41516 8.32918L9 11.6216L15.5848 8.32918C15.9553 8.14394 16.4058 8.29411 16.5911 8.66459C16.7763 9.03508 16.6261 9.48558 16.2556 9.67082L9.58299 13.0072C9.57817 13.0096 9.57246 13.0125 9.56594 13.0158C9.5023 13.0484 9.36089 13.1207 9.2021 13.1505C9.06853 13.1755 8.93146 13.1755 8.79789 13.1505C8.6391 13.1207 8.4977 13.0484 8.43405 13.0158C8.42753 13.0125 8.42182 13.0096 8.417 13.0072L1.74434 9.67082C1.37386 9.48558 1.22369 9.03508 1.40893 8.66459ZM1.40893 12.1247C1.59418 11.7542 2.04468 11.6041 2.41516 11.7893L9 15.0817L15.5848 11.7893C15.9553 11.6041 16.4058 11.7542 16.5911 12.1247C16.7763 12.4952 16.6261 12.9457 16.2556 13.1309L9.58299 16.4673C9.57817 16.4697 9.57247 16.4726 9.56595 16.4759C9.5023 16.5085 9.36089 16.5808 9.2021 16.6106C9.06853 16.6357 8.93146 16.6357 8.79789 16.6106C8.6391 16.5808 8.49769 16.5085 8.43405 16.4759C8.42753 16.4726 8.42182 16.4697 8.417 16.4673L1.74434 13.1309C1.37386 12.9457 1.22369 12.4952 1.40893 12.1247Z" />
|
||||
</svg>
|
After Width: | Height: | Size: 1.9 KiB |
@@ -0,0 +1,5 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 18 18" >
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M8.4583 7.13094L6.60858 6.68746C6.3905 6.63518 6.16154 6.60713 5.92405 6.60713C4.3115 6.60713 3.00427 7.91436 3.00427 9.52691C3.00427 11.1395 4.3115 12.4467 5.92405 12.4467C7.24744 12.4467 8.36881 11.5651 8.72548 10.3539L9.04242 9.2776H13.8426L13.8426 3.93535L8.4583 3.93535V7.13094ZM5.4583 5.13138C3.23625 5.3641 1.50427 7.24324 1.50427 9.52691C1.50427 11.9679 3.48308 13.9467 5.92405 13.9467C7.93065 13.9467 9.62493 12.6095 10.1644 10.7776H13.8426C14.6711 10.7776 15.3426 10.106 15.3426 9.2776V3.93535C15.3426 3.10692 14.6711 2.43535 13.8426 2.43535H8.4583C7.70971 2.43535 7.08919 2.98372 6.97655 3.70068C6.96454 3.77714 6.9583 3.85552 6.9583 3.93535V5.2288C6.62653 5.14926 6.28021 5.10713 5.92405 5.10713C5.76675 5.10713 5.61136 5.11535 5.4583 5.13138Z"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M11.1475 9.2776L8.10266 14.5515H14.9726L12.3191 9.95547L13.8417 9.27845C13.8419 9.27828 13.8425 9.27776 13.8426 9.2776C13.8426 9.27913 13.8426 9.27969 13.8426 9.27947L13.8426 9.2776C13.8426 9.27778 13.8427 9.27737 13.8426 9.2776C13.8428 9.27708 13.8435 9.27675 13.8435 9.2766C13.8436 9.27654 13.8436 9.2765 13.8435 9.2766C13.8435 9.27675 13.8428 9.27708 13.8426 9.2776L13.8426 3.93535L8.4583 3.93535L8.45832 9.2776H11.1475ZM14.7236 10.4918C15.0988 10.2191 15.3426 9.77685 15.3426 9.2776V3.93535C15.3426 3.10692 14.6711 2.43535 13.8426 2.43535H8.4583C7.62987 2.43535 6.9583 3.10692 6.9583 3.93535L6.95832 9.2776C6.95832 9.58297 7.04957 9.86703 7.2063 10.104C7.47474 10.5099 7.93527 10.7776 8.45832 10.7776H8.54944L6.80362 13.8015C6.22627 14.8015 6.94796 16.0515 8.10266 16.0515H14.9726C16.1273 16.0515 16.849 14.8015 16.2716 13.8015L14.4515 10.6489C14.548 10.606 14.6391 10.5532 14.7236 10.4918Z"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M13.8426 3.93535L8.4583 3.93535L8.45832 9.2776H13.8426L13.8426 3.93535ZM8.4583 2.43535C7.62987 2.43535 6.9583 3.10692 6.9583 3.93535L6.95832 9.2776C6.95832 10.106 7.62989 10.7776 8.45832 10.7776H13.8426C14.6711 10.7776 15.3426 10.106 15.3426 9.2776V3.93535C15.3426 3.10692 14.6711 2.43535 13.8426 2.43535H8.4583Z" />
|
||||
</svg>
|
After Width: | Height: | Size: 2.1 KiB |
@@ -0,0 +1,6 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 18 18">
|
||||
<path d="M7.275 3.39747C7.275 2.44478 8.04731 1.67247 9 1.67247C9.95269 1.67247 10.725 2.44478 10.725 3.39747C10.725 4.35016 9.95269 5.12247 9 5.12247C8.04731 5.12247 7.275 4.35016 7.275 3.39747Z"/>
|
||||
<path d="M13.05 12.7336C13.05 11.7809 13.8223 11.0086 14.775 11.0086C15.7277 11.0086 16.5 11.7809 16.5 12.7336C16.5 13.6863 15.7277 14.4586 14.775 14.4586C13.8223 14.4586 13.05 13.6863 13.05 12.7336Z" />
|
||||
<path d="M1.5 12.7336C1.5 11.7809 2.27231 11.0086 3.225 11.0086C4.17769 11.0086 4.95 11.7809 4.95 12.7336C4.95 13.6863 4.17769 14.4586 3.225 14.4586C2.27231 14.4586 1.5 13.6863 1.5 12.7336Z" />
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M6.47577 4.59792C6.28566 4.20775 5.81199 4.04174 5.44739 4.27718C4.59257 4.82918 3.87495 5.57494 3.35537 6.45819C2.83579 7.34145 2.53261 8.331 2.46543 9.34633C2.43677 9.7794 2.812 10.1128 3.24539 10.0894C3.67878 10.066 4.0047 9.69385 4.04974 9.26218C4.12336 8.55661 4.34733 7.87177 4.71008 7.25511C5.07284 6.63845 5.56261 6.10997 6.14355 5.70284C6.49897 5.45374 6.66587 4.98809 6.47577 4.59792ZM14.7543 10.0953C15.1877 10.1191 15.5632 9.78614 15.535 9.35303C15.4689 8.33764 15.1667 7.34777 14.648 6.46399C14.1294 5.5802 13.4125 4.83371 12.5583 4.28083C12.1939 4.04501 11.7201 4.21054 11.5295 4.60051C11.339 4.99049 11.5055 5.45631 11.8606 5.70577C12.4412 6.11351 12.9304 6.64248 13.2925 7.25951C13.6546 7.87655 13.8779 8.56161 13.9508 9.26726C13.9954 9.69898 14.3209 10.0714 14.7543 10.0953ZM6.03643 15.6186C5.64939 15.4222 5.55425 14.9294 5.79558 14.5686C6.03691 14.2079 6.52325 14.1176 6.91745 14.2992C7.56177 14.596 8.26499 14.753 8.98043 14.7558C9.69587 14.7586 10.4003 14.6072 11.0469 14.3154C11.4426 14.1369 11.9282 14.2311 12.1667 14.5937C12.4051 14.9563 12.3061 15.4484 11.9176 15.6417C11.0066 16.0951 9.99898 16.3315 8.97425 16.3275C7.94951 16.3235 6.94382 16.0791 6.03643 15.6186Z" />
|
||||
</svg>
|
After Width: | Height: | Size: 1.9 KiB |
@@ -0,0 +1,6 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 18 18" >
|
||||
<path d="M2.40921 14.9955C2.74759 15.3952 3.28934 15.595 4.03446 15.595V14.1936C3.74393 14.1936 3.53373 14.0912 3.40384 13.8863C3.27738 13.6815 3.21415 13.3342 3.21415 12.8446V11.3083C3.21415 10.0842 2.95096 9.31726 2.42459 9.00749V8.97752C2.95096 8.66275 3.21415 7.90583 3.21415 6.70673V5.11044C3.21415 4.24109 3.48758 3.80642 4.03446 3.80642V2.40498C3.28251 2.40498 2.73905 2.61482 2.40409 3.03451C2.06913 3.44919 1.90165 4.17115 1.90165 5.20037V6.87161C1.90165 7.82589 1.64188 8.30302 1.12235 8.30302V9.68198C1.64188 9.68198 1.90165 10.1416 1.90165 11.0609V12.8596C1.90165 13.8838 2.07083 14.5958 2.40921 14.9955Z"/>
|
||||
<path d="M15.5908 14.9955C15.2524 15.3952 14.7107 15.595 13.9655 15.595V14.1936C14.2561 14.1936 14.4663 14.0912 14.5962 13.8863C14.7226 13.6815 14.7859 13.3342 14.7859 12.8446V11.3083C14.7859 10.0842 15.049 9.31726 15.5754 9.00749V8.97752C15.049 8.66275 14.7859 7.90583 14.7859 6.70673V5.11044C14.7859 4.24109 14.5124 3.80642 13.9655 3.80642V2.40498C14.7175 2.40498 15.261 2.61482 15.5959 3.03451C15.9309 3.44919 16.0984 4.17115 16.0984 5.20037V6.87161C16.0984 7.82589 16.3581 8.30302 16.8777 8.30302V9.68198C16.3581 9.68198 16.0984 10.1416 16.0984 11.0609V12.8596C16.0984 13.8838 15.9292 14.5958 15.5908 14.9955Z"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M4.12446 15.595C4.12446 15.6447 4.08416 15.685 4.03446 15.685C3.27447 15.685 2.7023 15.4809 2.34052 15.0536C1.98023 14.628 1.81165 13.8876 1.81165 12.8596V11.0609C1.81165 10.6068 1.74697 10.2807 1.62847 10.071C1.51423 9.86886 1.34901 9.77198 1.12235 9.77198C1.07264 9.77198 1.03235 9.73169 1.03235 9.68198V8.30302C1.03235 8.25332 1.07264 8.21303 1.12235 8.21303C1.23797 8.21303 1.33489 8.18665 1.4163 8.13681C1.49791 8.08683 1.56895 8.0102 1.62778 7.90214C1.74691 7.68331 1.81165 7.34353 1.81165 6.87161V5.20037C1.81165 4.16717 1.97862 3.41818 2.33391 2.97816C2.69205 2.52958 3.26679 2.31498 4.03446 2.31498C4.08416 2.31498 4.12446 2.35528 4.12446 2.40498V3.80642C4.12446 3.85613 4.08416 3.89642 4.03446 3.89642C3.78954 3.89642 3.6144 3.99118 3.4954 4.18035C3.372 4.37651 3.30415 4.68229 3.30415 5.11044V6.70673C3.30415 7.84046 3.07112 8.62051 2.56503 8.99216C2.80368 9.1661 2.98111 9.43386 3.10188 9.78579C3.2379 10.1822 3.30415 10.6908 3.30415 11.3083V12.8446C3.30415 13.3312 3.36786 13.6563 3.48014 13.8386C3.59008 14.0116 3.76791 14.1036 4.03446 14.1036C4.08416 14.1036 4.12446 14.1439 4.12446 14.1936V15.595ZM3.40384 13.8863C3.27738 13.6815 3.21415 13.3342 3.21415 12.8446V11.3083C3.21415 10.1321 2.97117 9.37803 2.48522 9.04599C2.47453 9.03868 2.46373 9.03159 2.45281 9.02469C2.44349 9.01881 2.43408 9.01308 2.42459 9.00749V8.97752C2.43392 8.97194 2.44317 8.96622 2.45233 8.96037C2.46331 8.95335 2.47417 8.94613 2.48492 8.93871C2.97107 8.6031 3.21415 7.85911 3.21415 6.70673V5.11044C3.21415 4.24109 3.48758 3.80642 4.03446 3.80642V2.40498C4.00412 2.40498 3.97412 2.40532 3.94446 2.40601C3.23899 2.42226 2.72553 2.63176 2.40409 3.03451C2.06913 3.44919 1.90165 4.17115 1.90165 5.20037V6.87161C1.90165 7.82589 1.64188 8.30302 1.12235 8.30302V9.68198C1.64188 9.68198 1.90165 10.1416 1.90165 11.0609V12.8596C1.90165 13.8838 2.07083 14.5958 2.40921 14.9955C2.73382 15.3789 3.24556 15.5784 3.94446 15.594C3.97412 15.5947 4.00412 15.595 4.03446 15.595V14.1936C3.74393 14.1936 3.53373 14.0912 3.40384 13.8863ZM13.9655 15.685C13.9158 15.685 13.8755 15.6447 13.8755 15.595V14.1936C13.8755 14.1439 13.9158 14.1036 13.9655 14.1036C14.2321 14.1036 14.4099 14.0116 14.5199 13.8386C14.6321 13.6563 14.6959 13.3312 14.6959 12.8446V11.3083C14.6959 10.6908 14.7621 10.1822 14.8981 9.78579C15.0189 9.43386 15.1963 9.16609 15.435 8.99216C14.9289 8.6205 14.6959 7.84046 14.6959 6.70673V5.11044C14.6959 4.68229 14.628 4.37651 14.5046 4.18035C14.3856 3.99118 14.2105 3.89642 13.9655 3.89642C13.9158 3.89642 13.8755 3.85613 13.8755 3.80642V2.40498C13.8755 2.35528 13.9158 2.31498 13.9655 2.31498C14.7332 2.31498 15.3079 2.52957 15.6661 2.97811C16.0214 3.41813 16.1884 4.16713 16.1884 5.20037V6.87161C16.1884 7.34353 16.2531 7.68331 16.3722 7.90214C16.4311 8.0102 16.5021 8.08683 16.5837 8.13681C16.6651 8.18665 16.762 8.21303 16.8777 8.21303C16.9274 8.21303 16.9677 8.25332 16.9677 8.30302V9.68198C16.9677 9.73169 16.9274 9.77198 16.8777 9.77198C16.651 9.77198 16.4858 9.86886 16.3715 10.071C16.253 10.2807 16.1884 10.6068 16.1884 11.0609V12.8596C16.1884 13.8876 16.0198 14.628 15.6595 15.0536C15.2977 15.4809 14.7255 15.685 13.9655 15.685ZM15.5959 3.03451C15.2745 2.63176 14.761 2.42226 14.0556 2.40601C14.0259 2.40532 13.9959 2.40498 13.9655 2.40498V3.80642C14.5124 3.80642 14.7859 4.24109 14.7859 5.11044V6.70673C14.7859 7.85911 15.0289 8.6031 15.5151 8.93871C15.5258 8.94613 15.5367 8.95335 15.5477 8.96037C15.5568 8.96622 15.5661 8.97194 15.5754 8.97752V9.00749C15.5659 9.01308 15.5565 9.01881 15.5472 9.02469C15.5363 9.03158 15.5255 9.03868 15.5148 9.04599C15.0288 9.37802 14.7859 10.1321 14.7859 11.3083V12.8446C14.7859 13.3342 14.7226 13.6815 14.5962 13.8863C14.4663 14.0912 14.2561 14.1936 13.9655 14.1936V15.595C13.9959 15.595 14.0259 15.5947 14.0556 15.594C14.7544 15.5784 15.2662 15.3789 15.5908 14.9955C15.9292 14.5958 16.0984 13.8838 16.0984 12.8596V11.0609C16.0984 10.1416 16.3581 9.68198 16.8777 9.68198V8.30302C16.3581 8.30302 16.0984 7.82589 16.0984 6.87161V5.20037C16.0984 4.17115 15.9309 3.44919 15.5959 3.03451Z" />
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M5.81804 5.81801C6.11093 5.52512 6.58581 5.52512 6.8787 5.81801L9.00001 7.93932L11.1213 5.81801C11.4142 5.52512 11.8891 5.52512 12.182 5.81801C12.4749 6.1109 12.4749 6.58578 12.182 6.87867L10.0607 8.99998L12.182 11.1213C12.4749 11.4142 12.4749 11.8891 12.182 12.182C11.8891 12.4749 11.4142 12.4749 11.1213 12.182L9.00001 10.0606L6.87868 12.182C6.58579 12.4749 6.11091 12.4749 5.81802 12.182C5.52513 11.8891 5.52513 11.4142 5.81802 11.1213L7.93935 8.99998L5.81804 6.87867C5.52515 6.58578 5.52515 6.1109 5.81804 5.81801Z"/>
|
||||
</svg>
|
After Width: | Height: | Size: 5.8 KiB |
Before Width: | Height: | Size: 3.1 KiB After Width: | Height: | Size: 3.1 KiB |
Before Width: | Height: | Size: 3.9 KiB After Width: | Height: | Size: 3.9 KiB |
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
Before Width: | Height: | Size: 1.7 KiB After Width: | Height: | Size: 1.7 KiB |
Before Width: | Height: | Size: 3.1 KiB After Width: | Height: | Size: 3.1 KiB |
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 2.2 KiB |
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB |
Before Width: | Height: | Size: 6.6 KiB After Width: | Height: | Size: 6.6 KiB |
Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 2.8 KiB |
Before Width: | Height: | Size: 1.8 KiB After Width: | Height: | Size: 1.8 KiB |
@@ -0,0 +1,9 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M12.05 1.5C6.25106 1.5 1.55005 6.20101 1.55005 12C1.55005 17.799 6.25106 22.5 12.05 22.5C17.849 22.5 22.55 17.799 22.55 12C22.55 6.20101 17.849 1.5 12.05 1.5ZM4.45357 10.6776L5.23449 9.8967C6.52836 8.60283 8.62614 8.60282 9.92001 9.89669L15.3864 15.3631C13.6613 17.0883 10.8642 17.0883 9.13909 15.3631L4.45357 10.6776ZM13.0437 11.4585L13.8246 10.6776C14.8765 9.62569 16.4598 9.42898 17.7104 10.0875C18.2671 10.3806 18.8755 10.6306 19.4995 10.5504C19.4995 10.5504 19.0284 11.5308 18.6367 12.1034C17.8653 13.2312 16.1674 14.5822 16.1674 14.5822L13.0437 11.4585Z" fill="url(#paint0_linear_15358_11488)"/>
|
||||
<defs>
|
||||
<linearGradient id="paint0_linear_15358_11488" x1="12.05" y1="1.5" x2="12.05" y2="22.5" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#00BCA6"/>
|
||||
<stop offset="1" stop-color="#00AF9A"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
</svg>
|
After Width: | Height: | Size: 978 B |
@@ -58,4 +58,4 @@ const MyNumberInput = (props: Props) => {
|
||||
);
|
||||
};
|
||||
|
||||
export default MyNumberInput;
|
||||
export default React.memo(MyNumberInput);
|
||||
|
@@ -13,4 +13,4 @@ const SearchInput = (props: InputProps) => {
|
||||
);
|
||||
};
|
||||
|
||||
export default SearchInput;
|
||||
export default React.memo(SearchInput);
|
||||
|
@@ -17,4 +17,4 @@ const MyBox = ({ text, isLoading, children, size, ...props }: Props, ref: any) =
|
||||
);
|
||||
};
|
||||
|
||||
export default forwardRef(MyBox);
|
||||
export default React.memo(forwardRef(MyBox));
|
||||
|
@@ -44,4 +44,4 @@ const Loading = ({
|
||||
);
|
||||
};
|
||||
|
||||
export default Loading;
|
||||
export default React.memo(Loading);
|
||||
|
@@ -77,4 +77,4 @@ const InputSlider = ({
|
||||
);
|
||||
};
|
||||
|
||||
export default InputSlider;
|
||||
export default React.memo(InputSlider);
|
||||
|
@@ -15,4 +15,4 @@ const QuestionTip = ({ label, maxW, ...props }: Props) => {
|
||||
);
|
||||
};
|
||||
|
||||
export default QuestionTip;
|
||||
export default React.memo(QuestionTip);
|
||||
|