Compare commits
24 Commits
gru/projec
...
v4.9.1-alp
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
93f7747904 | ||
|
|
6aa5e2c200 | ||
|
|
d8712d4092 | ||
|
|
561a496f80 | ||
|
|
bd369d3b09 | ||
|
|
3e21030536 | ||
|
|
7ec4ba7067 | ||
|
|
2d22af3cce | ||
|
|
4346c5703a | ||
|
|
f71ab0caeb | ||
|
|
c131c2a7dc | ||
|
|
d052d0de53 | ||
|
|
d1ce3e2936 | ||
|
|
c301dafca7 | ||
|
|
1a3613cd2c | ||
|
|
30f83f848d | ||
|
|
ac7091f8d6 | ||
|
|
16832caaf6 | ||
|
|
a3df9ea531 | ||
|
|
bcd0b010a6 | ||
|
|
3f794baf2e | ||
|
|
92b2ecc381 | ||
|
|
4dbe41db0e | ||
|
|
f9dd170895 |
@@ -5,4 +5,5 @@ node_modules
|
||||
docSite/
|
||||
*.md
|
||||
|
||||
pnpm-lock.yaml
|
||||
cl100l_base.ts
|
||||
@@ -69,7 +69,7 @@ Project tech stack: NextJs + TS + ChakraUI + MongoDB + PostgreSQL (PG Vector plu
|
||||
|
||||
> When using [Sealos](https://sealos.io) services, there is no need to purchase servers or domain names. It supports high concurrency and dynamic scaling, and the database application uses the kubeblocks database, which far exceeds the simple Docker container deployment in terms of IO performance.
|
||||
<div align="center">
|
||||
[](https://cloud.sealos.io/?openapp=system-fastdeploy%3FtemplateName%3Dfastgpt)
|
||||
[](https://cloud.sealos.io/?openapp=system-fastdeploy%3FtemplateName%3Dfastgpt&uid=fnWRt09fZP)
|
||||
</div>
|
||||
|
||||
Give it a 2-4 minute wait after deployment as it sets up the database. Initially, it might be a too slow since we're using the basic settings.
|
||||
|
||||
@@ -94,7 +94,7 @@ https://github.com/labring/FastGPT/assets/15308462/7d3a38df-eb0e-4388-9250-2409b
|
||||
|
||||
- **⚡ デプロイ**
|
||||
|
||||
[](https://cloud.sealos.io/?openapp=system-fastdeploy%3FtemplateName%3Dfastgpt)
|
||||
[](https://cloud.sealos.io/?openapp=system-fastdeploy%3FtemplateName%3Dfastgpt&uid=fnWRt09fZP)
|
||||
|
||||
デプロイ 後、データベースをセットアップするので、2~4分待 ってください。基本設定 を 使 っているので、最初 は 少 し 遅 いかもしれません。
|
||||
|
||||
|
||||
@@ -100,7 +100,7 @@ services:
|
||||
exec docker-entrypoint.sh "$$@" &
|
||||
|
||||
# 等待MongoDB服务启动
|
||||
until mongo -u myusername -p mypassword --authenticationDatabase admin --eval "print('waited for connection')" > /dev/null 2>&1; do
|
||||
until mongo -u myusername -p mypassword --authenticationDatabase admin --eval "print('waited for connection')"; do
|
||||
echo "Waiting for MongoDB to start..."
|
||||
sleep 2
|
||||
done
|
||||
|
||||
@@ -58,7 +58,7 @@ services:
|
||||
exec docker-entrypoint.sh "$$@" &
|
||||
|
||||
# 等待MongoDB服务启动
|
||||
until mongo -u myusername -p mypassword --authenticationDatabase admin --eval "print('waited for connection')" > /dev/null 2>&1; do
|
||||
until mongo -u myusername -p mypassword --authenticationDatabase admin --eval "print('waited for connection')"; do
|
||||
echo "Waiting for MongoDB to start..."
|
||||
sleep 2
|
||||
done
|
||||
|
||||
@@ -41,7 +41,7 @@ services:
|
||||
exec docker-entrypoint.sh "$$@" &
|
||||
|
||||
# 等待MongoDB服务启动
|
||||
until mongo -u myusername -p mypassword --authenticationDatabase admin --eval "print('waited for connection')" > /dev/null 2>&1; do
|
||||
until mongo -u myusername -p mypassword --authenticationDatabase admin --eval "print('waited for connection')"; do
|
||||
echo "Waiting for MongoDB to start..."
|
||||
sleep 2
|
||||
done
|
||||
|
||||
@@ -44,7 +44,7 @@ weight: 707
|
||||
|
||||
#### 1. 申请 Sealos AI proxy API Key
|
||||
|
||||
[点击打开 Sealos Pdf parser 官网](https://cloud.sealos.run/?uid=fnWRt09fZP&openapp=system-aiproxy),并进行对应 API Key 的申请。
|
||||
[点击打开 Sealos Pdf parser 官网](https://hzh.sealos.run/?uid=fnWRt09fZP&openapp=system-aiproxy),并进行对应 API Key 的申请。
|
||||
|
||||
#### 2. 修改 FastGPT 配置文件
|
||||
|
||||
|
||||
@@ -29,7 +29,7 @@ weight: 744
|
||||
|
||||
{{% alert icon=" " context="info" %}}
|
||||
- [SiliconCloud(硅基流动)](https://cloud.siliconflow.cn/i/TR9Ym0c4): 提供开源模型调用的平台。
|
||||
- [Sealos AIProxy](https://cloud.sealos.run/?uid=fnWRt09fZP&openapp=system-aiproxy): 提供国内各家模型代理,无需逐一申请 api。
|
||||
- [Sealos AIProxy](https://hzh.sealos.run/?uid=fnWRt09fZP&openapp=system-aiproxy): 提供国内各家模型代理,无需逐一申请 api。
|
||||
{{% /alert %}}
|
||||
|
||||
在 OneAPI 配置好模型后,你就可以打开 FastGPT 页面,启用对应模型了。
|
||||
|
||||
@@ -23,7 +23,7 @@ FastGPT 目前采用模型分离的部署方案,FastGPT 中只兼容 OpenAI
|
||||
### Sealos 版本
|
||||
|
||||
* 北京区: [点击部署 OneAPI](https://hzh.sealos.run/?openapp=system-template%3FtemplateName%3Done-api)
|
||||
* 新加坡区(可用 GPT) [点击部署 OneAPI](https://cloud.sealos.io/?openapp=system-template%3FtemplateName%3Done-api)
|
||||
* 新加坡区(可用 GPT) [点击部署 OneAPI](https://cloud.sealos.io/?openapp=system-template%3FtemplateName%3Done-api&uid=fnWRt09fZP)
|
||||
|
||||

|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ weight: 951
|
||||
|
||||
## 登录 Sealos
|
||||
|
||||
[Sealos](https://cloud.sealos.io/)
|
||||
[Sealos](https://cloud.sealos.io?uid=fnWRt09fZP)
|
||||
|
||||
## 创建应用
|
||||
|
||||
|
||||
@@ -26,13 +26,13 @@ FastGPT 使用了 one-api 项目来管理模型池,其可以兼容 OpenAI 、A
|
||||
|
||||
新加披区的服务器在国外,可以直接访问 OpenAI,但国内用户需要梯子才可以正常访问新加坡区。国际区价格稍贵,点击下面按键即可部署👇
|
||||
|
||||
<a href="https://template.cloud.sealos.io/deploy?templateName=fastgpt" rel="external" target="_blank"><img src="https://cdn.jsdelivr.net/gh/labring-actions/templates@main/Deploy-on-Sealos.svg" alt="Deploy on Sealos"/></a>
|
||||
<a href="https://template.cloud.sealos.io/deploy?templateName=fastgpt&uid=fnWRt09fZP" rel="external" target="_blank"><img src="https://cdn.jsdelivr.net/gh/labring-actions/templates@main/Deploy-on-Sealos.svg" alt="Deploy on Sealos"/></a>
|
||||
|
||||
### 北京区
|
||||
|
||||
北京区服务提供商为火山云,国内用户可以稳定访问,但无法访问 OpenAI 等境外服务,价格约为新加坡区的 1/4。点击下面按键即可部署👇
|
||||
|
||||
<a href="https://bja.sealos.run/?openapp=system-template%3FtemplateName%3Dfastgpt" rel="external" target="_blank"><img src="https://raw.githubusercontent.com/labring-actions/templates/main/Deploy-on-Sealos.svg" alt="Deploy on Sealos"/></a>
|
||||
<a href="https://bja.sealos.run/?openapp=system-template%3FtemplateName%3Dfastgpt&uid=fnWRt09fZP" rel="external" target="_blank"><img src="https://raw.githubusercontent.com/labring-actions/templates/main/Deploy-on-Sealos.svg" alt="Deploy on Sealos"/></a>
|
||||
|
||||
### 1. 开始部署
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ FastGPT V4.5 引入 PgVector0.5 版本的 HNSW 索引,极大的提高了知识
|
||||
|
||||
## PgVector升级:Sealos 部署方案
|
||||
|
||||
1. 点击[Sealos桌面](https://cloud.sealos.io)的数据库应用。
|
||||
1. 点击[Sealos桌面](https://cloud.sealos.io?uid=fnWRt09fZP)的数据库应用。
|
||||
2. 点击【pg】数据库的详情。
|
||||
3. 点击右上角的重启,等待重启完成。
|
||||
4. 点击左侧的一键链接,等待打开 Terminal。
|
||||
|
||||
@@ -4,7 +4,7 @@ description: 'FastGPT V4.8.23 更新说明'
|
||||
icon: 'upgrade'
|
||||
draft: false
|
||||
toc: true
|
||||
weight: 802
|
||||
weight: 801
|
||||
---
|
||||
|
||||
## 更新指南
|
||||
|
||||
@@ -4,7 +4,7 @@ description: 'FastGPT V4.9.0 更新说明'
|
||||
icon: 'upgrade'
|
||||
draft: false
|
||||
toc: true
|
||||
weight: 801
|
||||
weight: 800
|
||||
---
|
||||
|
||||
|
||||
|
||||
36
docSite/content/zh-cn/docs/development/upgrading/491.md
Normal file
@@ -0,0 +1,36 @@
|
||||
---
|
||||
title: 'V4.9.1'
|
||||
description: 'FastGPT V4.9.1 更新说明'
|
||||
icon: 'upgrade'
|
||||
draft: false
|
||||
toc: true
|
||||
weight: 799
|
||||
---
|
||||
|
||||
## 🚀 新增内容
|
||||
|
||||
1. 商业版支持单团队模式,更好的管理内部成员。
|
||||
2. 知识库分块阅读器。
|
||||
3. API 知识库支持 PDF 增强解析。
|
||||
4. 邀请团队成员,改为邀请链接模式。
|
||||
5. 支持混合检索权重设置。
|
||||
6. 支持重排模型选择和权重设置,同时调整了知识库搜索权重计算方式,改成 搜索权重 + 重排权重,而不是向量检索权重+全文检索权重+重排权重。
|
||||
|
||||
## ⚙️ 优化
|
||||
|
||||
1. 知识库数据输入框交互
|
||||
2. 应用拉取绑定知识库数据交由后端处理。
|
||||
3. 增加依赖包安全版本检测,并升级部分依赖包。
|
||||
4. 模型测试代码。
|
||||
5. 优化思考过程解析逻辑:只要配置了模型支持思考,均会解析 <think> 标签,不会因为对话时,关闭思考而不解析。
|
||||
|
||||
## 🐛 修复
|
||||
|
||||
1. 最大响应 tokens 提示显示错误的问题。
|
||||
2. HTTP Node 中,字符串包含换行符时,会解析失败。
|
||||
3. 知识库问题优化中,未传递历史记录。
|
||||
4. 错误提示翻译缺失。
|
||||
5. 内容提取节点,array 类型 schema 错误。
|
||||
6. 模型渠道测试时,实际未指定渠道测试。
|
||||
7. 新增自定义模型时,会把默认模型字段也保存,导致默认模型误判。
|
||||
8. 修复 promp 模式工具调用,未判空思考链,导致 UI 错误展示。
|
||||
@@ -30,7 +30,7 @@ FastGPT 升级包括两个步骤:
|
||||
|
||||
## Sealos 修改镜像
|
||||
|
||||
1. 打开 [Sealos Cloud](https://cloud.sealos.io/), 找到桌面上的应用管理
|
||||
1. 打开 [Sealos Cloud](https://cloud.sealos.io?uid=fnWRt09fZP), 找到桌面上的应用管理
|
||||
|
||||

|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ weight: 303
|
||||
|
||||
这里介绍在 Sealos 中部署 SearXNG 的方法。Docker 部署,可以直接参考 [SearXNG 官方教程](https://github.com/searxng/searxng)。
|
||||
|
||||
点击打开 [Sealos 北京区](https://bja.sealos.run/),点击应用部署,并新建一个应用:
|
||||
点击打开 [Sealos 北京区](https://bja.sealos.run?uid=fnWRt09fZP),点击应用部署,并新建一个应用:
|
||||
|
||||
| 打开应用部署 | 点击新建应用 |
|
||||
| --- | --- |
|
||||
@@ -130,7 +130,7 @@ doi_resolvers:
|
||||
default_doi_resolver: 'oadoi.org'
|
||||
```
|
||||
|
||||
国内目前只有 Bing 引擎可以正常用,所以上面的配置只配置了 bing 引擎。如果在海外部署,可以使用[Sealos 新加坡可用区](https://cloud.sealos.io/),并配置其他搜索引擎,可以参考[SearXNG 默认配置文件](https://github.com/searxng/searxng/blob/master/searx/settings.yml), 从里面复制一些 engine 配置。例如:
|
||||
国内目前只有 Bing 引擎可以正常用,所以上面的配置只配置了 bing 引擎。如果在海外部署,可以使用[Sealos 新加坡可用区](https://cloud.sealos.io?uid=fnWRt09fZP),并配置其他搜索引擎,可以参考[SearXNG 默认配置文件](https://github.com/searxng/searxng/blob/master/searx/settings.yml), 从里面复制一些 engine 配置。例如:
|
||||
|
||||
```
|
||||
- name: duckduckgo
|
||||
|
||||
@@ -27,7 +27,7 @@ weight: 510
|
||||
|
||||
## sealos部署服务
|
||||
|
||||
[访问sealos](https://cloud.sealos.run/) 登录进来之后打开「应用管理」-> 「新建应用」。
|
||||
[访问sealos](https://hzh.sealos.run?uid=fnWRt09fZP) 登录进来之后打开「应用管理」-> 「新建应用」。
|
||||
- 应用名:称随便填写
|
||||
- 镜像名:私人微信填写 aibotk/wechat-assistant 企业微信填写 aibotk/worker-assistant
|
||||
- cpu和内存建议 1c1g
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
"previewIcon": "node ./scripts/icon/index.js",
|
||||
"api:gen": "tsc ./scripts/openapi/index.ts && node ./scripts/openapi/index.js && npx @redocly/cli build-docs ./scripts/openapi/openapi.json -o ./projects/app/public/openapi/index.html",
|
||||
"create:i18n": "node ./scripts/i18n/index.js",
|
||||
"test": "vitest run --exclude './projects/app/src/test/**'",
|
||||
"test": "vitest run --exclude 'test/cases/spec'",
|
||||
"test:all": "vitest run",
|
||||
"test:workflow": "vitest run workflow"
|
||||
},
|
||||
|
||||
@@ -24,7 +24,10 @@ export enum TeamErrEnum {
|
||||
cannotModifyRootOrg = 'cannotModifyRootOrg',
|
||||
cannotDeleteNonEmptyOrg = 'cannotDeleteNonEmptyOrg',
|
||||
cannotDeleteDefaultGroup = 'cannotDeleteDefaultGroup',
|
||||
userNotActive = 'userNotActive'
|
||||
userNotActive = 'userNotActive',
|
||||
invitationLinkInvalid = 'invitationLinkInvalid',
|
||||
youHaveBeenInTheTeam = 'youHaveBeenInTheTeam',
|
||||
tooManyInvitations = 'tooManyInvitations'
|
||||
}
|
||||
|
||||
const teamErr = [
|
||||
@@ -112,6 +115,18 @@ const teamErr = [
|
||||
{
|
||||
statusText: TeamErrEnum.cannotDeleteNonEmptyOrg,
|
||||
message: i18nT('common:code_error.team_error.cannot_delete_non_empty_org')
|
||||
},
|
||||
{
|
||||
statusText: TeamErrEnum.invitationLinkInvalid,
|
||||
message: i18nT('common:code_error.team_error.invitation_link_invalid')
|
||||
},
|
||||
{
|
||||
statusText: TeamErrEnum.youHaveBeenInTheTeam,
|
||||
message: i18nT('common:code_error.team_error.you_have_been_in_the_team')
|
||||
},
|
||||
{
|
||||
statusText: TeamErrEnum.tooManyInvitations,
|
||||
message: i18nT('common:code_error.team_error.too_many_invitations')
|
||||
}
|
||||
];
|
||||
|
||||
|
||||
@@ -93,7 +93,7 @@ ${mdSplitString}
|
||||
|
||||
/*
|
||||
1. 自定义分隔符:不需要重叠,不需要小块合并
|
||||
2. Markdown 标题:不需要重叠;标题嵌套共享,不需要小块合并
|
||||
2. Markdown 标题:不需要重叠;标题嵌套共享,需要小块合并
|
||||
3. 特殊 markdown 语法:不需要重叠,需要小块合并
|
||||
4. 段落:尽可能保证它是一个完整的段落。
|
||||
5. 标点分割:重叠
|
||||
@@ -227,7 +227,7 @@ const commonSplit = (props: SplitProps): SplitResponse => {
|
||||
}): string[] => {
|
||||
const isMarkdownStep = checkIsMarkdownSplit(step);
|
||||
const isCustomStep = checkIsCustomStep(step);
|
||||
const forbidConcat = isMarkdownStep || isCustomStep; // forbid=true时候,lastText肯定为空
|
||||
const forbidConcat = isCustomStep; // forbid=true时候,lastText肯定为空
|
||||
|
||||
// oversize
|
||||
if (step >= stepReges.length) {
|
||||
|
||||
@@ -6,7 +6,7 @@ import type {
|
||||
EmbeddingModelItemType,
|
||||
AudioSpeechModels,
|
||||
STTModelType,
|
||||
ReRankModelItemType
|
||||
RerankModelItemType
|
||||
} from '../../../core/ai/model.d';
|
||||
import { SubTypeEnum } from '../../../support/wallet/sub/constants';
|
||||
|
||||
@@ -35,7 +35,7 @@ export type FastGPTConfigFileType = {
|
||||
// Abandon
|
||||
llmModels?: ChatModelItemType[];
|
||||
vectorModels?: EmbeddingModelItemType[];
|
||||
reRankModels?: ReRankModelItemType[];
|
||||
reRankModels?: RerankModelItemType[];
|
||||
audioSpeechModels?: TTSModelType[];
|
||||
whisperModel?: STTModelType;
|
||||
};
|
||||
|
||||
2
packages/global/core/ai/model.d.ts
vendored
@@ -72,7 +72,7 @@ export type EmbeddingModelItemType = PriceType &
|
||||
queryConfig?: Record<string, any>; // Custom parameters for query
|
||||
};
|
||||
|
||||
export type ReRankModelItemType = PriceType &
|
||||
export type RerankModelItemType = PriceType &
|
||||
BaseModelItemType & {
|
||||
type: ModelTypeEnum.rerank;
|
||||
};
|
||||
|
||||
23
packages/global/core/app/type.d.ts
vendored
@@ -71,6 +71,20 @@ export type AppDetailType = AppSchema & {
|
||||
permission: AppPermission;
|
||||
};
|
||||
|
||||
export type AppDatasetSearchParamsType = {
|
||||
searchMode: `${DatasetSearchModeEnum}`;
|
||||
limit?: number; // limit max tokens
|
||||
similarity?: number;
|
||||
embeddingWeight?: number; // embedding weight, fullText weight = 1 - embeddingWeight
|
||||
|
||||
usingReRank?: boolean;
|
||||
rerankModel?: string;
|
||||
rerankWeight?: number;
|
||||
|
||||
datasetSearchUsingExtensionQuery?: boolean;
|
||||
datasetSearchExtensionModel?: string;
|
||||
datasetSearchExtensionBg?: string;
|
||||
};
|
||||
export type AppSimpleEditFormType = {
|
||||
// templateId: string;
|
||||
aiSettings: {
|
||||
@@ -88,14 +102,7 @@ export type AppSimpleEditFormType = {
|
||||
};
|
||||
dataset: {
|
||||
datasets: SelectedDatasetType;
|
||||
searchMode: `${DatasetSearchModeEnum}`;
|
||||
similarity?: number;
|
||||
limit?: number;
|
||||
usingReRank?: boolean;
|
||||
datasetSearchUsingExtensionQuery?: boolean;
|
||||
datasetSearchExtensionModel?: string;
|
||||
datasetSearchExtensionBg?: string;
|
||||
};
|
||||
} & AppDatasetSearchParamsType;
|
||||
selectedTools: FlowNodeTemplateType[];
|
||||
chatConfig: AppChatConfigType;
|
||||
};
|
||||
|
||||
@@ -24,9 +24,11 @@ export const getDefaultAppForm = (): AppSimpleEditFormType => {
|
||||
dataset: {
|
||||
datasets: [],
|
||||
similarity: 0.4,
|
||||
limit: 1500,
|
||||
limit: 3000,
|
||||
searchMode: DatasetSearchModeEnum.embedding,
|
||||
usingReRank: false,
|
||||
rerankModel: '',
|
||||
rerankWeight: 0.5,
|
||||
datasetSearchUsingExtensionQuery: true,
|
||||
datasetSearchExtensionBg: ''
|
||||
},
|
||||
@@ -106,10 +108,24 @@ export const appWorkflow2Form = ({
|
||||
defaultAppForm.dataset.searchMode =
|
||||
findInputValueByKey(node.inputs, NodeInputKeyEnum.datasetSearchMode) ||
|
||||
DatasetSearchModeEnum.embedding;
|
||||
defaultAppForm.dataset.embeddingWeight = findInputValueByKey(
|
||||
node.inputs,
|
||||
NodeInputKeyEnum.datasetSearchEmbeddingWeight
|
||||
);
|
||||
// Rerank
|
||||
defaultAppForm.dataset.usingReRank = !!findInputValueByKey(
|
||||
node.inputs,
|
||||
NodeInputKeyEnum.datasetSearchUsingReRank
|
||||
);
|
||||
defaultAppForm.dataset.rerankModel = findInputValueByKey(
|
||||
node.inputs,
|
||||
NodeInputKeyEnum.datasetSearchRerankModel
|
||||
);
|
||||
defaultAppForm.dataset.rerankWeight = findInputValueByKey(
|
||||
node.inputs,
|
||||
NodeInputKeyEnum.datasetSearchRerankWeight
|
||||
);
|
||||
// Query extension
|
||||
defaultAppForm.dataset.datasetSearchUsingExtensionQuery = findInputValueByKey(
|
||||
node.inputs,
|
||||
NodeInputKeyEnum.datasetSearchUsingExtensionQuery
|
||||
|
||||
@@ -256,7 +256,7 @@ export const GPTMessages2Chats = (
|
||||
) {
|
||||
const value: AIChatItemValueItemType[] = [];
|
||||
|
||||
if (typeof item.reasoning_text === 'string') {
|
||||
if (typeof item.reasoning_text === 'string' && item.reasoning_text) {
|
||||
value.push({
|
||||
type: ChatItemValueTypeEnum.reasoning,
|
||||
reasoning: {
|
||||
@@ -323,7 +323,7 @@ export const GPTMessages2Chats = (
|
||||
interactive: item.interactive
|
||||
});
|
||||
}
|
||||
if (typeof item.content === 'string') {
|
||||
if (typeof item.content === 'string' && item.content) {
|
||||
const lastValue = value[value.length - 1];
|
||||
if (lastValue && lastValue.type === ChatItemValueTypeEnum.text && lastValue.text) {
|
||||
lastValue.text.content += item.content;
|
||||
|
||||
1
packages/global/core/chat/type.d.ts
vendored
@@ -134,6 +134,7 @@ export type ChatItemType = (UserChatItemType | SystemChatItemType | AIChatItemTy
|
||||
|
||||
// Frontend type
|
||||
export type ChatSiteItemType = (UserChatItemType | SystemChatItemType | AIChatItemType) & {
|
||||
_id?: string;
|
||||
dataId: string;
|
||||
status: `${ChatStatusEnum}`;
|
||||
moduleName?: string;
|
||||
|
||||
@@ -185,7 +185,7 @@ export enum SearchScoreTypeEnum {
|
||||
}
|
||||
export const SearchScoreTypeMap = {
|
||||
[SearchScoreTypeEnum.embedding]: {
|
||||
label: i18nT('common:core.dataset.search.score.embedding'),
|
||||
label: i18nT('common:core.dataset.search.mode.embedding'),
|
||||
desc: i18nT('common:core.dataset.search.score.embedding desc'),
|
||||
showScore: true
|
||||
},
|
||||
|
||||
@@ -16,23 +16,23 @@ export const DatasetDataIndexMap: Record<
|
||||
}
|
||||
> = {
|
||||
[DatasetDataIndexTypeEnum.default]: {
|
||||
label: i18nT('dataset:data_index_default'),
|
||||
label: i18nT('common:data_index_default'),
|
||||
color: 'gray'
|
||||
},
|
||||
[DatasetDataIndexTypeEnum.custom]: {
|
||||
label: i18nT('dataset:data_index_custom'),
|
||||
label: i18nT('common:data_index_custom'),
|
||||
color: 'blue'
|
||||
},
|
||||
[DatasetDataIndexTypeEnum.summary]: {
|
||||
label: i18nT('dataset:data_index_summary'),
|
||||
label: i18nT('common:data_index_summary'),
|
||||
color: 'green'
|
||||
},
|
||||
[DatasetDataIndexTypeEnum.question]: {
|
||||
label: i18nT('dataset:data_index_question'),
|
||||
label: i18nT('common:data_index_question'),
|
||||
color: 'red'
|
||||
},
|
||||
[DatasetDataIndexTypeEnum.image]: {
|
||||
label: i18nT('dataset:data_index_image'),
|
||||
label: i18nT('common:data_index_image'),
|
||||
color: 'purple'
|
||||
}
|
||||
};
|
||||
|
||||
7
packages/global/core/dataset/type.d.ts
vendored
@@ -112,12 +112,15 @@ export type DatasetDataSchemaType = {
|
||||
tmbId: string;
|
||||
datasetId: string;
|
||||
collectionId: string;
|
||||
datasetId: string;
|
||||
collectionId: string;
|
||||
chunkIndex: number;
|
||||
updateTime: Date;
|
||||
q: string; // large chunks or question
|
||||
a: string; // answer or custom content
|
||||
history?: {
|
||||
q: string;
|
||||
a: string;
|
||||
updateTime: Date;
|
||||
}[];
|
||||
forbid?: boolean;
|
||||
fullTextToken: string;
|
||||
indexes: DatasetDataIndexItemType[];
|
||||
|
||||
7
packages/global/core/workflow/api.d.ts
vendored
@@ -1,7 +1,12 @@
|
||||
import { EmbeddingModelItemType } from '../ai/model.d';
|
||||
import { NodeInputKeyEnum } from './constants';
|
||||
|
||||
export type SelectedDatasetType = { datasetId: string }[];
|
||||
export type SelectedDatasetType = {
|
||||
datasetId: string;
|
||||
avatar: string;
|
||||
name: string;
|
||||
vectorModel: EmbeddingModelItemType;
|
||||
}[];
|
||||
|
||||
export type HttpBodyType<T = Record<string, any>> = {
|
||||
// [NodeInputKeyEnum.addInputParam]: Record<string, any>;
|
||||
|
||||
@@ -154,7 +154,12 @@ export enum NodeInputKeyEnum {
|
||||
datasetSimilarity = 'similarity',
|
||||
datasetMaxTokens = 'limit',
|
||||
datasetSearchMode = 'searchMode',
|
||||
datasetSearchEmbeddingWeight = 'embeddingWeight',
|
||||
|
||||
datasetSearchUsingReRank = 'usingReRank',
|
||||
datasetSearchRerankWeight = 'rerankWeight',
|
||||
datasetSearchRerankModel = 'rerankModel',
|
||||
|
||||
datasetSearchUsingExtensionQuery = 'datasetSearchUsingExtensionQuery',
|
||||
datasetSearchExtensionModel = 'datasetSearchExtensionModel',
|
||||
datasetSearchExtensionBg = 'datasetSearchExtensionBg',
|
||||
|
||||
@@ -133,6 +133,9 @@ export type DispatchNodeResponseType = {
|
||||
similarity?: number;
|
||||
limit?: number;
|
||||
searchMode?: `${DatasetSearchModeEnum}`;
|
||||
embeddingWeight?: number;
|
||||
rerankModel?: string;
|
||||
rerankWeight?: number;
|
||||
searchUsingReRank?: boolean;
|
||||
queryExtensionResult?: {
|
||||
model: string;
|
||||
|
||||
@@ -4,7 +4,10 @@ export type ContextExtractAgentItemType = {
|
||||
valueType:
|
||||
| WorkflowIOValueTypeEnum.string
|
||||
| WorkflowIOValueTypeEnum.number
|
||||
| WorkflowIOValueTypeEnum.boolean;
|
||||
| WorkflowIOValueTypeEnum.boolean
|
||||
| WorkflowIOValueTypeEnum.arrayString
|
||||
| WorkflowIOValueTypeEnum.arrayNumber
|
||||
| WorkflowIOValueTypeEnum.arrayBoolean;
|
||||
desc: string;
|
||||
key: string;
|
||||
required: boolean;
|
||||
|
||||
@@ -64,6 +64,14 @@ export const DatasetSearchModule: FlowNodeTemplateType = {
|
||||
valueType: WorkflowIOValueTypeEnum.string,
|
||||
value: DatasetSearchModeEnum.embedding
|
||||
},
|
||||
{
|
||||
key: NodeInputKeyEnum.datasetSearchEmbeddingWeight,
|
||||
renderTypeList: [FlowNodeInputTypeEnum.hidden],
|
||||
label: '',
|
||||
valueType: WorkflowIOValueTypeEnum.number,
|
||||
value: 0.5
|
||||
},
|
||||
// Rerank
|
||||
{
|
||||
key: NodeInputKeyEnum.datasetSearchUsingReRank,
|
||||
renderTypeList: [FlowNodeInputTypeEnum.hidden],
|
||||
@@ -71,6 +79,20 @@ export const DatasetSearchModule: FlowNodeTemplateType = {
|
||||
valueType: WorkflowIOValueTypeEnum.boolean,
|
||||
value: false
|
||||
},
|
||||
{
|
||||
key: NodeInputKeyEnum.datasetSearchRerankModel,
|
||||
renderTypeList: [FlowNodeInputTypeEnum.hidden],
|
||||
label: '',
|
||||
valueType: WorkflowIOValueTypeEnum.string
|
||||
},
|
||||
{
|
||||
key: NodeInputKeyEnum.datasetSearchRerankWeight,
|
||||
renderTypeList: [FlowNodeInputTypeEnum.hidden],
|
||||
label: '',
|
||||
valueType: WorkflowIOValueTypeEnum.number,
|
||||
value: 0.5
|
||||
},
|
||||
// Query Extension
|
||||
{
|
||||
key: NodeInputKeyEnum.datasetSearchUsingExtensionQuery,
|
||||
renderTypeList: [FlowNodeInputTypeEnum.hidden],
|
||||
@@ -91,6 +113,7 @@ export const DatasetSearchModule: FlowNodeTemplateType = {
|
||||
valueType: WorkflowIOValueTypeEnum.string,
|
||||
value: ''
|
||||
},
|
||||
|
||||
{
|
||||
key: NodeInputKeyEnum.authTmbId,
|
||||
renderTypeList: [FlowNodeInputTypeEnum.hidden],
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
"encoding": "^0.1.13",
|
||||
"js-yaml": "^4.1.0",
|
||||
"jschardet": "3.1.1",
|
||||
"nanoid": "^4.0.1",
|
||||
"nanoid": "^5.1.3",
|
||||
"next": "14.2.21",
|
||||
"openai": "4.61.0",
|
||||
"openapi-types": "^12.1.3",
|
||||
|
||||
3
packages/global/support/outLink/type.d.ts
vendored
@@ -63,6 +63,8 @@ export type OutLinkSchema<T extends OutlinkAppType = undefined> = {
|
||||
responseDetail: boolean;
|
||||
// whether to hide the node status
|
||||
showNodeStatus?: boolean;
|
||||
// wheter to show the full text reader
|
||||
// showFullText?: boolean;
|
||||
// whether to show the complete quote
|
||||
showRawSource?: boolean;
|
||||
|
||||
@@ -89,6 +91,7 @@ export type OutLinkEditType<T = undefined> = {
|
||||
name: string;
|
||||
responseDetail?: OutLinkSchema<T>['responseDetail'];
|
||||
showNodeStatus?: OutLinkSchema<T>['showNodeStatus'];
|
||||
// showFullText?: OutLinkSchema<T>['showFullText'];
|
||||
showRawSource?: OutLinkSchema<T>['showRawSource'];
|
||||
// response when request
|
||||
immediateResponse?: string;
|
||||
|
||||
@@ -14,29 +14,28 @@ export const TeamMemberRoleMap = {
|
||||
};
|
||||
|
||||
export enum TeamMemberStatusEnum {
|
||||
waiting = 'waiting',
|
||||
active = 'active',
|
||||
reject = 'reject',
|
||||
leave = 'leave'
|
||||
leave = 'leave',
|
||||
forbidden = 'forbidden'
|
||||
}
|
||||
|
||||
export const TeamMemberStatusMap = {
|
||||
[TeamMemberStatusEnum.waiting]: {
|
||||
label: 'user.team.member.waiting',
|
||||
color: 'orange.600'
|
||||
},
|
||||
[TeamMemberStatusEnum.active]: {
|
||||
label: 'user.team.member.active',
|
||||
color: 'green.600'
|
||||
},
|
||||
[TeamMemberStatusEnum.reject]: {
|
||||
label: 'user.team.member.reject',
|
||||
color: 'red.600'
|
||||
},
|
||||
[TeamMemberStatusEnum.leave]: {
|
||||
label: 'user.team.member.leave',
|
||||
color: 'red.600'
|
||||
},
|
||||
[TeamMemberStatusEnum.forbidden]: {
|
||||
label: 'user.team.member.forbidden',
|
||||
color: 'red.600'
|
||||
}
|
||||
};
|
||||
|
||||
export const notLeaveStatus = { $ne: TeamMemberStatusEnum.leave };
|
||||
export const notLeaveStatus = {
|
||||
$not: {
|
||||
$in: [TeamMemberStatusEnum.leave, TeamMemberStatusEnum.forbidden]
|
||||
}
|
||||
};
|
||||
|
||||
@@ -40,11 +40,6 @@ export type UpdateInviteProps = {
|
||||
status: TeamMemberSchema['status'];
|
||||
};
|
||||
|
||||
export type UpdateStatusProps = {
|
||||
tmbId: string;
|
||||
status: TeamMemberSchema['status'];
|
||||
};
|
||||
|
||||
export type InviteMemberResponse = Record<
|
||||
'invite' | 'inValid' | 'inTeam',
|
||||
{ username: string; userId: string }[]
|
||||
|
||||
@@ -300,6 +300,9 @@ export const readRawContentByFileBuffer = async ({
|
||||
return systemParse();
|
||||
};
|
||||
|
||||
const start = Date.now();
|
||||
addLog.debug(`Start parse file`, { extension });
|
||||
|
||||
let { rawText, formatText, imageList } = await (async () => {
|
||||
if (extension === 'pdf') {
|
||||
return await pdfParseFn();
|
||||
@@ -307,6 +310,8 @@ export const readRawContentByFileBuffer = async ({
|
||||
return await systemParse();
|
||||
})();
|
||||
|
||||
addLog.debug(`Parse file success, time: ${Date.now() - start}ms. Uploading file image.`);
|
||||
|
||||
// markdown data format
|
||||
if (imageList) {
|
||||
await batchRun(imageList, async (item) => {
|
||||
@@ -341,5 +346,7 @@ export const readRawContentByFileBuffer = async ({
|
||||
}
|
||||
}
|
||||
|
||||
addLog.debug(`Upload file image success, time: ${Date.now() - start}ms`);
|
||||
|
||||
return { rawText, formatText, imageList };
|
||||
};
|
||||
|
||||
@@ -38,6 +38,27 @@ export class PgVectorCtrl {
|
||||
await PgClient.query(
|
||||
`CREATE INDEX CONCURRENTLY IF NOT EXISTS create_time_index ON ${DatasetVectorTableName} USING btree(createtime);`
|
||||
);
|
||||
// 10w rows
|
||||
// await PgClient.query(`
|
||||
// ALTER TABLE modeldata SET (
|
||||
// autovacuum_vacuum_scale_factor = 0.1,
|
||||
// autovacuum_analyze_scale_factor = 0.05,
|
||||
// autovacuum_vacuum_threshold = 50,
|
||||
// autovacuum_analyze_threshold = 50,
|
||||
// autovacuum_vacuum_cost_delay = 20,
|
||||
// autovacuum_vacuum_cost_limit = 200
|
||||
// );`);
|
||||
|
||||
// 100w rows
|
||||
// await PgClient.query(`
|
||||
// ALTER TABLE modeldata SET (
|
||||
// autovacuum_vacuum_scale_factor = 0.01,
|
||||
// autovacuum_analyze_scale_factor = 0.02,
|
||||
// autovacuum_vacuum_threshold = 1000,
|
||||
// autovacuum_analyze_threshold = 1000,
|
||||
// autovacuum_vacuum_cost_delay = 10,
|
||||
// autovacuum_vacuum_cost_limit = 2000
|
||||
// );`)
|
||||
|
||||
addLog.info('init pg successful');
|
||||
} catch (error) {
|
||||
|
||||
@@ -6,10 +6,12 @@ import { getSTTModel } from '../model';
|
||||
|
||||
export const aiTranscriptions = async ({
|
||||
model,
|
||||
fileStream
|
||||
fileStream,
|
||||
headers
|
||||
}: {
|
||||
model: string;
|
||||
fileStream: fs.ReadStream;
|
||||
headers?: Record<string, string>;
|
||||
}) => {
|
||||
const data = new FormData();
|
||||
data.append('model', model);
|
||||
@@ -30,7 +32,8 @@ export const aiTranscriptions = async ({
|
||||
Authorization: modelData.requestAuth
|
||||
? `Bearer ${modelData.requestAuth}`
|
||||
: aiAxiosConfig.authorization,
|
||||
...data.getHeaders()
|
||||
...data.getHeaders(),
|
||||
...headers
|
||||
},
|
||||
data: data
|
||||
});
|
||||
|
||||
@@ -76,6 +76,10 @@ export const createChatCompletion = async ({
|
||||
timeout: formatTimeout
|
||||
});
|
||||
|
||||
addLog.debug(`Start create chat completion`, {
|
||||
model: body.model
|
||||
});
|
||||
|
||||
const response = await ai.chat.completions.create(body, {
|
||||
...options,
|
||||
...(modelConstantsData.requestUrl ? { path: modelConstantsData.requestUrl } : {}),
|
||||
|
||||
@@ -76,7 +76,7 @@
|
||||
{
|
||||
"model": "qwen-max",
|
||||
"name": "Qwen-max",
|
||||
"maxContext": 8000,
|
||||
"maxContext": 32000,
|
||||
"maxResponse": 4000,
|
||||
"quoteMaxToken": 6000,
|
||||
"maxTemperature": 1,
|
||||
|
||||
@@ -8,7 +8,7 @@ import {
|
||||
EmbeddingModelItemType,
|
||||
TTSModelType,
|
||||
STTModelType,
|
||||
ReRankModelItemType
|
||||
RerankModelItemType
|
||||
} from '@fastgpt/global/core/ai/model.d';
|
||||
import { debounce } from 'lodash';
|
||||
import {
|
||||
@@ -94,7 +94,7 @@ export const loadSystemModels = async (init = false) => {
|
||||
global.embeddingModelMap = new Map<string, EmbeddingModelItemType>();
|
||||
global.ttsModelMap = new Map<string, TTSModelType>();
|
||||
global.sttModelMap = new Map<string, STTModelType>();
|
||||
global.reRankModelMap = new Map<string, ReRankModelItemType>();
|
||||
global.reRankModelMap = new Map<string, RerankModelItemType>();
|
||||
// @ts-ignore
|
||||
global.systemDefaultModel = {};
|
||||
|
||||
|
||||
@@ -8,10 +8,11 @@ type GetVectorProps = {
|
||||
model: EmbeddingModelItemType;
|
||||
input: string;
|
||||
type?: `${EmbeddingTypeEnm}`;
|
||||
headers?: Record<string, string>;
|
||||
};
|
||||
|
||||
// text to vector
|
||||
export async function getVectorsByText({ model, input, type }: GetVectorProps) {
|
||||
export async function getVectorsByText({ model, input, type, headers }: GetVectorProps) {
|
||||
if (!input) {
|
||||
return Promise.reject({
|
||||
code: 500,
|
||||
@@ -35,13 +36,12 @@ export async function getVectorsByText({ model, input, type }: GetVectorProps) {
|
||||
model.requestUrl
|
||||
? {
|
||||
path: model.requestUrl,
|
||||
headers: model.requestAuth
|
||||
? {
|
||||
Authorization: `Bearer ${model.requestAuth}`
|
||||
}
|
||||
: undefined
|
||||
headers: {
|
||||
...(model.requestAuth ? { Authorization: `Bearer ${model.requestAuth}` } : {}),
|
||||
...headers
|
||||
}
|
||||
}
|
||||
: {}
|
||||
: { headers }
|
||||
)
|
||||
.then(async (res) => {
|
||||
if (!res.data) {
|
||||
|
||||
@@ -38,7 +38,7 @@ export function getSTTModel(model?: string) {
|
||||
}
|
||||
|
||||
export const getDefaultRerankModel = () => global?.systemDefaultModel.rerank!;
|
||||
export function getReRankModel(model?: string) {
|
||||
export function getRerankModel(model?: string) {
|
||||
if (!model) return getDefaultRerankModel();
|
||||
return global.reRankModelMap.get(model) || getDefaultRerankModel();
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ import { addLog } from '../../../common/system/log';
|
||||
import { POST } from '../../../common/api/serverRequest';
|
||||
import { getDefaultRerankModel } from '../model';
|
||||
import { getAxiosConfig } from '../config';
|
||||
import { ReRankModelItemType } from '@fastgpt/global/core/ai/model.d';
|
||||
import { RerankModelItemType } from '@fastgpt/global/core/ai/model.d';
|
||||
|
||||
type PostReRankResponse = {
|
||||
id: string;
|
||||
@@ -16,11 +16,13 @@ type ReRankCallResult = { id: string; score?: number }[];
|
||||
export function reRankRecall({
|
||||
model = getDefaultRerankModel(),
|
||||
query,
|
||||
documents
|
||||
documents,
|
||||
headers
|
||||
}: {
|
||||
model?: ReRankModelItemType;
|
||||
model?: RerankModelItemType;
|
||||
query: string;
|
||||
documents: { id: string; text: string }[];
|
||||
headers?: Record<string, string>;
|
||||
}): Promise<ReRankCallResult> {
|
||||
if (!model) {
|
||||
return Promise.reject('no rerank model');
|
||||
@@ -41,7 +43,8 @@ export function reRankRecall({
|
||||
},
|
||||
{
|
||||
headers: {
|
||||
Authorization: model.requestAuth ? `Bearer ${model.requestAuth}` : authorization
|
||||
Authorization: model.requestAuth ? `Bearer ${model.requestAuth}` : authorization,
|
||||
...headers
|
||||
},
|
||||
timeout: 30000
|
||||
}
|
||||
|
||||
8
packages/service/core/ai/type.d.ts
vendored
@@ -1,7 +1,7 @@
|
||||
import { ModelTypeEnum } from '@fastgpt/global/core/ai/model';
|
||||
import {
|
||||
STTModelType,
|
||||
ReRankModelItemType,
|
||||
RerankModelItemType,
|
||||
TTSModelType,
|
||||
EmbeddingModelItemType,
|
||||
LLMModelItemType
|
||||
@@ -18,7 +18,7 @@ export type SystemModelItemType =
|
||||
| EmbeddingModelItemType
|
||||
| TTSModelType
|
||||
| STTModelType
|
||||
| ReRankModelItemType;
|
||||
| RerankModelItemType;
|
||||
|
||||
export type SystemDefaultModelType = {
|
||||
[ModelTypeEnum.llm]?: LLMModelItemType;
|
||||
@@ -28,7 +28,7 @@ export type SystemDefaultModelType = {
|
||||
[ModelTypeEnum.embedding]?: EmbeddingModelItemType;
|
||||
[ModelTypeEnum.tts]?: TTSModelType;
|
||||
[ModelTypeEnum.stt]?: STTModelType;
|
||||
[ModelTypeEnum.rerank]?: ReRankModelItemType;
|
||||
[ModelTypeEnum.rerank]?: RerankModelItemType;
|
||||
};
|
||||
|
||||
declare global {
|
||||
@@ -38,7 +38,7 @@ declare global {
|
||||
var embeddingModelMap: Map<string, EmbeddingModelItemType>;
|
||||
var ttsModelMap: Map<string, TTSModelType>;
|
||||
var sttModelMap: Map<string, STTModelType>;
|
||||
var reRankModelMap: Map<string, ReRankModelItemType>;
|
||||
var reRankModelMap: Map<string, RerankModelItemType>;
|
||||
|
||||
var systemActiveModelList: SystemModelItemType[];
|
||||
var systemDefaultModel: SystemDefaultModelType;
|
||||
|
||||
@@ -132,7 +132,7 @@ export const parseReasoningStreamContent = () => {
|
||||
let endTagBuffer = '';
|
||||
|
||||
/*
|
||||
parseReasoning - 只控制是否主动解析 <think></think>,如果接口已经解析了,仍然会返回 think 内容。
|
||||
parseThinkTag - 只控制是否主动解析 <think></think>,如果接口已经解析了,则不再解析。
|
||||
*/
|
||||
const parsePart = (
|
||||
part: {
|
||||
@@ -143,13 +143,13 @@ export const parseReasoningStreamContent = () => {
|
||||
};
|
||||
}[];
|
||||
},
|
||||
parseReasoning = false
|
||||
parseThinkTag = false
|
||||
): [string, string] => {
|
||||
const content = part.choices?.[0]?.delta?.content || '';
|
||||
|
||||
// @ts-ignore
|
||||
const reasoningContent = part.choices?.[0]?.delta?.reasoning_content || '';
|
||||
if (reasoningContent || !parseReasoning) {
|
||||
if (reasoningContent || !parseThinkTag) {
|
||||
isInThinkTag = false;
|
||||
return [reasoningContent, content];
|
||||
}
|
||||
|
||||
149
packages/service/core/app/utils.ts
Normal file
@@ -0,0 +1,149 @@
|
||||
import { MongoDataset } from '../dataset/schema';
|
||||
import { getEmbeddingModel } from '../ai/model';
|
||||
import { FlowNodeTypeEnum } from '@fastgpt/global/core/workflow/node/constant';
|
||||
import { NodeInputKeyEnum } from '@fastgpt/global/core/workflow/constants';
|
||||
import type { StoreNodeItemType } from '@fastgpt/global/core/workflow/type/node';
|
||||
|
||||
export async function listAppDatasetDataByTeamIdAndDatasetIds({
|
||||
teamId,
|
||||
datasetIdList
|
||||
}: {
|
||||
teamId?: string;
|
||||
datasetIdList: string[];
|
||||
}) {
|
||||
const myDatasets = await MongoDataset.find({
|
||||
_id: { $in: datasetIdList },
|
||||
...(teamId && { teamId })
|
||||
}).lean();
|
||||
|
||||
return myDatasets.map((item) => ({
|
||||
datasetId: String(item._id),
|
||||
avatar: item.avatar,
|
||||
name: item.name,
|
||||
vectorModel: getEmbeddingModel(item.vectorModel)
|
||||
}));
|
||||
}
|
||||
|
||||
export async function rewriteAppWorkflowToDetail({
|
||||
nodes,
|
||||
teamId,
|
||||
isRoot
|
||||
}: {
|
||||
nodes: StoreNodeItemType[];
|
||||
teamId: string;
|
||||
isRoot: boolean;
|
||||
}) {
|
||||
const datasetIdSet = new Set<string>();
|
||||
|
||||
// Get all dataset ids from nodes
|
||||
nodes.forEach((node) => {
|
||||
if (node.flowNodeType !== FlowNodeTypeEnum.datasetSearchNode) return;
|
||||
|
||||
const input = node.inputs.find((item) => item.key === NodeInputKeyEnum.datasetSelectList);
|
||||
if (!input) return;
|
||||
|
||||
const rawValue = input.value as undefined | { datasetId: string }[] | { datasetId: string };
|
||||
if (!rawValue) return;
|
||||
|
||||
const datasetIds = Array.isArray(rawValue)
|
||||
? rawValue.map((v) => v?.datasetId).filter((id) => !!id && typeof id === 'string')
|
||||
: rawValue?.datasetId
|
||||
? [String(rawValue.datasetId)]
|
||||
: [];
|
||||
|
||||
datasetIds.forEach((id) => datasetIdSet.add(id));
|
||||
});
|
||||
|
||||
if (datasetIdSet.size === 0) return;
|
||||
|
||||
// Load dataset list
|
||||
const datasetList = await listAppDatasetDataByTeamIdAndDatasetIds({
|
||||
teamId: isRoot ? undefined : teamId,
|
||||
datasetIdList: Array.from(datasetIdSet)
|
||||
});
|
||||
const datasetMap = new Map(datasetList.map((ds) => [String(ds.datasetId), ds]));
|
||||
|
||||
// Rewrite dataset ids, add dataset info to nodes
|
||||
if (datasetList.length > 0) {
|
||||
nodes.forEach((node) => {
|
||||
if (node.flowNodeType !== FlowNodeTypeEnum.datasetSearchNode) return;
|
||||
|
||||
node.inputs.forEach((item) => {
|
||||
if (item.key !== NodeInputKeyEnum.datasetSelectList) return;
|
||||
|
||||
const val = item.value as undefined | { datasetId: string }[] | { datasetId: string };
|
||||
|
||||
if (Array.isArray(val)) {
|
||||
item.value = val
|
||||
.map((v) => {
|
||||
const data = datasetMap.get(String(v.datasetId));
|
||||
if (!data)
|
||||
return {
|
||||
datasetId: v.datasetId,
|
||||
avatar: '',
|
||||
name: 'Dataset not found',
|
||||
vectorModel: ''
|
||||
};
|
||||
return {
|
||||
datasetId: data.datasetId,
|
||||
avatar: data.avatar,
|
||||
name: data.name,
|
||||
vectorModel: data.vectorModel
|
||||
};
|
||||
})
|
||||
.filter(Boolean);
|
||||
} else if (typeof val === 'object' && val !== null) {
|
||||
const data = datasetMap.get(String(val.datasetId));
|
||||
if (!data) {
|
||||
item.value = [
|
||||
{
|
||||
datasetId: val.datasetId,
|
||||
avatar: '',
|
||||
name: 'Dataset not found',
|
||||
vectorModel: ''
|
||||
}
|
||||
];
|
||||
} else {
|
||||
item.value = [
|
||||
{
|
||||
datasetId: data.datasetId,
|
||||
avatar: data.avatar,
|
||||
name: data.name,
|
||||
vectorModel: data.vectorModel
|
||||
}
|
||||
];
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
return nodes;
|
||||
}
|
||||
|
||||
export async function rewriteAppWorkflowToSimple(formatNodes: StoreNodeItemType[]) {
|
||||
formatNodes.forEach((node) => {
|
||||
if (node.flowNodeType !== FlowNodeTypeEnum.datasetSearchNode) return;
|
||||
|
||||
node.inputs.forEach((input) => {
|
||||
if (input.key === NodeInputKeyEnum.datasetSelectList) {
|
||||
const val = input.value as undefined | { datasetId: string }[] | { datasetId: string };
|
||||
if (!val) {
|
||||
input.value = [];
|
||||
} else if (Array.isArray(val)) {
|
||||
input.value = val
|
||||
.map((dataset: { datasetId: string }) => ({
|
||||
datasetId: dataset.datasetId
|
||||
}))
|
||||
.filter((item) => !!item.datasetId);
|
||||
} else if (typeof val === 'object' && val !== null) {
|
||||
input.value = [
|
||||
{
|
||||
datasetId: val.datasetId
|
||||
}
|
||||
];
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
@@ -15,6 +15,7 @@ import { AppChatConfigType } from '@fastgpt/global/core/app/type';
|
||||
import { mergeChatResponseData } from '@fastgpt/global/core/chat/utils';
|
||||
import { pushChatLog } from './pushChatLog';
|
||||
import { FlowNodeTypeEnum } from '@fastgpt/global/core/workflow/node/constant';
|
||||
import { DispatchNodeResponseKeyEnum } from '@fastgpt/global/core/workflow/runtime/constants';
|
||||
|
||||
type Props = {
|
||||
chatId: string;
|
||||
@@ -73,9 +74,44 @@ export async function saveChat({
|
||||
(node) => node.flowNodeType === FlowNodeTypeEnum.pluginInput
|
||||
)?.inputs;
|
||||
|
||||
// Format save chat content: Remove quote q/a
|
||||
const processedContent = content.map((item) => {
|
||||
if (item.obj === ChatRoleEnum.AI) {
|
||||
const nodeResponse = item[DispatchNodeResponseKeyEnum.nodeResponse];
|
||||
|
||||
if (nodeResponse) {
|
||||
return {
|
||||
...item,
|
||||
[DispatchNodeResponseKeyEnum.nodeResponse]: nodeResponse.map((responseItem) => {
|
||||
if (
|
||||
responseItem.moduleType === FlowNodeTypeEnum.datasetSearchNode &&
|
||||
responseItem.quoteList
|
||||
) {
|
||||
return {
|
||||
...responseItem,
|
||||
quoteList: responseItem.quoteList.map((quote: any) => ({
|
||||
id: quote.id,
|
||||
chunkIndex: quote.chunkIndex,
|
||||
datasetId: quote.datasetId,
|
||||
collectionId: quote.collectionId,
|
||||
sourceId: quote.sourceId,
|
||||
sourceName: quote.sourceName,
|
||||
score: quote.score,
|
||||
tokens: quote.tokens
|
||||
}))
|
||||
};
|
||||
}
|
||||
return responseItem;
|
||||
})
|
||||
};
|
||||
}
|
||||
}
|
||||
return item;
|
||||
});
|
||||
|
||||
await mongoSessionRun(async (session) => {
|
||||
const [{ _id: chatItemIdHuman }, { _id: chatItemIdAi }] = await MongoChatItem.insertMany(
|
||||
content.map((item) => ({
|
||||
processedContent.map((item) => ({
|
||||
chatId,
|
||||
teamId,
|
||||
tmbId,
|
||||
|
||||
@@ -111,11 +111,13 @@ export const useApiDatasetRequest = ({ apiServer }: { apiServer: APIFileServer }
|
||||
const getFileContent = async ({
|
||||
teamId,
|
||||
tmbId,
|
||||
apiFileId
|
||||
apiFileId,
|
||||
customPdfParse
|
||||
}: {
|
||||
teamId: string;
|
||||
tmbId: string;
|
||||
apiFileId: string;
|
||||
customPdfParse?: boolean;
|
||||
}) => {
|
||||
const data = await request<APIFileContentResponse>(
|
||||
`/v1/file/content`,
|
||||
@@ -133,7 +135,8 @@ export const useApiDatasetRequest = ({ apiServer }: { apiServer: APIFileServer }
|
||||
teamId,
|
||||
tmbId,
|
||||
url: previewUrl,
|
||||
relatedId: apiFileId
|
||||
relatedId: apiFileId,
|
||||
customPdfParse
|
||||
});
|
||||
return rawText;
|
||||
}
|
||||
|
||||
@@ -40,6 +40,15 @@ const DatasetDataSchema = new Schema({
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
history: {
|
||||
type: [
|
||||
{
|
||||
q: String,
|
||||
a: String,
|
||||
updateTime: Date
|
||||
}
|
||||
]
|
||||
},
|
||||
indexes: {
|
||||
type: [
|
||||
{
|
||||
@@ -89,15 +98,11 @@ try {
|
||||
chunkIndex: 1,
|
||||
updateTime: -1
|
||||
});
|
||||
// FullText tmp 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 });
|
||||
|
||||
DatasetDataSchema.index({ initFullText: 1 });
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
|
||||
@@ -127,7 +127,8 @@ export const readApiServerFileContent = async ({
|
||||
yuqueServer,
|
||||
apiFileId,
|
||||
teamId,
|
||||
tmbId
|
||||
tmbId,
|
||||
customPdfParse
|
||||
}: {
|
||||
apiServer?: APIFileServer;
|
||||
feishuServer?: FeishuServer;
|
||||
@@ -135,9 +136,15 @@ export const readApiServerFileContent = async ({
|
||||
apiFileId: string;
|
||||
teamId: string;
|
||||
tmbId: string;
|
||||
customPdfParse?: boolean;
|
||||
}) => {
|
||||
if (apiServer) {
|
||||
return useApiDatasetRequest({ apiServer }).getFileContent({ teamId, tmbId, apiFileId });
|
||||
return useApiDatasetRequest({ apiServer }).getFileContent({
|
||||
teamId,
|
||||
tmbId,
|
||||
apiFileId,
|
||||
customPdfParse
|
||||
});
|
||||
}
|
||||
|
||||
if (feishuServer || yuqueServer) {
|
||||
|
||||
@@ -27,6 +27,7 @@ import { ChatItemType } from '@fastgpt/global/core/chat/type';
|
||||
import { POST } from '../../../common/api/plusRequest';
|
||||
import { NodeInputKeyEnum } from '@fastgpt/global/core/workflow/constants';
|
||||
import { datasetSearchQueryExtension } from './utils';
|
||||
import type { RerankModelItemType } from '@fastgpt/global/core/ai/model.d';
|
||||
|
||||
export type SearchDatasetDataProps = {
|
||||
histories: ChatItemType[];
|
||||
@@ -39,7 +40,11 @@ export type SearchDatasetDataProps = {
|
||||
[NodeInputKeyEnum.datasetSimilarity]?: number; // min distance
|
||||
[NodeInputKeyEnum.datasetMaxTokens]: number; // max Token limit
|
||||
[NodeInputKeyEnum.datasetSearchMode]?: `${DatasetSearchModeEnum}`;
|
||||
[NodeInputKeyEnum.datasetSearchEmbeddingWeight]?: number;
|
||||
|
||||
[NodeInputKeyEnum.datasetSearchUsingReRank]?: boolean;
|
||||
[NodeInputKeyEnum.datasetSearchRerankModel]?: RerankModelItemType;
|
||||
[NodeInputKeyEnum.datasetSearchRerankWeight]?: number;
|
||||
|
||||
/*
|
||||
{
|
||||
@@ -75,13 +80,16 @@ export type SearchDatasetDataResponse = {
|
||||
};
|
||||
|
||||
export const datasetDataReRank = async ({
|
||||
rerankModel,
|
||||
data,
|
||||
query
|
||||
}: {
|
||||
rerankModel?: RerankModelItemType;
|
||||
data: SearchDataResponseItemType[];
|
||||
query: string;
|
||||
}): Promise<SearchDataResponseItemType[]> => {
|
||||
const results = await reRankRecall({
|
||||
model: rerankModel,
|
||||
query,
|
||||
documents: data.map((item) => ({
|
||||
id: item.id,
|
||||
@@ -154,7 +162,10 @@ export async function searchDatasetData(
|
||||
similarity = 0,
|
||||
limit: maxTokens,
|
||||
searchMode = DatasetSearchModeEnum.embedding,
|
||||
embeddingWeight = 0.5,
|
||||
usingReRank = false,
|
||||
rerankModel,
|
||||
rerankWeight = 0.5,
|
||||
datasetIds = [],
|
||||
collectionFilterMatch
|
||||
} = props;
|
||||
@@ -711,6 +722,7 @@ export async function searchDatasetData(
|
||||
});
|
||||
try {
|
||||
return await datasetDataReRank({
|
||||
rerankModel,
|
||||
query: reRankQuery,
|
||||
data: filterSameDataResults
|
||||
});
|
||||
@@ -721,11 +733,26 @@ export async function searchDatasetData(
|
||||
})();
|
||||
|
||||
// embedding recall and fullText recall rrf concat
|
||||
const rrfConcatResults = datasetSearchResultConcat([
|
||||
{ k: 60, list: embeddingRecallResults },
|
||||
{ k: 60, list: fullTextRecallResults },
|
||||
{ k: 58, list: reRankResults }
|
||||
const baseK = 120;
|
||||
const embK = Math.round(baseK * (1 - embeddingWeight)); // 搜索结果的 k 值
|
||||
const fullTextK = Math.round(baseK * embeddingWeight); // rerank 结果的 k 值
|
||||
|
||||
const rrfSearchResult = datasetSearchResultConcat([
|
||||
{ k: embK, list: embeddingRecallResults },
|
||||
{ k: fullTextK, list: fullTextRecallResults }
|
||||
]);
|
||||
const rrfConcatResults = (() => {
|
||||
if (reRankResults.length === 0) return rrfSearchResult;
|
||||
if (rerankWeight === 1) return reRankResults;
|
||||
|
||||
const searchK = Math.round(baseK * rerankWeight); // 搜索结果的 k 值
|
||||
const rerankK = Math.round(baseK * (1 - rerankWeight)); // rerank 结果的 k 值
|
||||
|
||||
return datasetSearchResultConcat([
|
||||
{ k: searchK, list: rrfSearchResult },
|
||||
{ k: rerankK, list: reRankResults }
|
||||
]);
|
||||
})();
|
||||
|
||||
// remove same q and a data
|
||||
set = new Set<string>();
|
||||
|
||||
@@ -9,7 +9,11 @@ import {
|
||||
import { ChatItemValueTypeEnum, ChatRoleEnum } from '@fastgpt/global/core/chat/constants';
|
||||
import { createChatCompletion } from '../../../ai/config';
|
||||
import type { ContextExtractAgentItemType } from '@fastgpt/global/core/workflow/template/system/contextExtract/type';
|
||||
import { NodeInputKeyEnum, NodeOutputKeyEnum } from '@fastgpt/global/core/workflow/constants';
|
||||
import {
|
||||
NodeInputKeyEnum,
|
||||
NodeOutputKeyEnum,
|
||||
toolValueTypeList
|
||||
} from '@fastgpt/global/core/workflow/constants';
|
||||
import { DispatchNodeResponseKeyEnum } from '@fastgpt/global/core/workflow/runtime/constants';
|
||||
import type { ModuleDispatchProps } from '@fastgpt/global/core/workflow/runtime/type';
|
||||
import { Prompt_ExtractJson } from '@fastgpt/global/core/ai/prompt/agent';
|
||||
@@ -192,10 +196,13 @@ ${description ? `- ${description}` : ''}
|
||||
}
|
||||
> = {};
|
||||
extractKeys.forEach((item) => {
|
||||
const jsonSchema = (
|
||||
toolValueTypeList.find((type) => type.value === item.valueType) || toolValueTypeList[0]
|
||||
)?.jsonSchema;
|
||||
properties[item.key] = {
|
||||
type: item.valueType || 'string',
|
||||
...jsonSchema,
|
||||
description: item.desc,
|
||||
...(item.enum ? { enum: item.enum.split('\n') } : {})
|
||||
...(item.enum ? { enum: item.enum.split('\n').filter(Boolean) } : {})
|
||||
};
|
||||
});
|
||||
// function body
|
||||
|
||||
@@ -1,11 +1,6 @@
|
||||
import { createChatCompletion } from '../../../../ai/config';
|
||||
import { filterGPTMessageByMaxContext, loadRequestMessages } from '../../../../chat/utils';
|
||||
import {
|
||||
ChatCompletion,
|
||||
StreamChatType,
|
||||
ChatCompletionMessageParam,
|
||||
ChatCompletionAssistantMessageParam
|
||||
} from '@fastgpt/global/core/ai/type';
|
||||
import { StreamChatType, ChatCompletionMessageParam } from '@fastgpt/global/core/ai/type';
|
||||
import { NextApiResponse } from 'next';
|
||||
import { responseWriteController } from '../../../../../common/response';
|
||||
import { SseResponseEventEnum } from '@fastgpt/global/core/workflow/runtime/constants';
|
||||
|
||||
@@ -208,6 +208,7 @@ export const dispatchChatCompletion = async (props: ChatProps): Promise<ChatResp
|
||||
res,
|
||||
stream: response,
|
||||
aiChatReasoning,
|
||||
parseThinkTag: modelConstantsData.reasoning,
|
||||
isResponseAnswerText,
|
||||
workflowStreamResponse
|
||||
});
|
||||
@@ -513,12 +514,14 @@ async function streamResponse({
|
||||
stream,
|
||||
workflowStreamResponse,
|
||||
aiChatReasoning,
|
||||
parseThinkTag,
|
||||
isResponseAnswerText
|
||||
}: {
|
||||
res: NextApiResponse;
|
||||
stream: StreamChatType;
|
||||
workflowStreamResponse?: WorkflowResponseType;
|
||||
aiChatReasoning?: boolean;
|
||||
parseThinkTag?: boolean;
|
||||
isResponseAnswerText?: boolean;
|
||||
}) {
|
||||
const write = responseWriteController({
|
||||
@@ -535,7 +538,7 @@ async function streamResponse({
|
||||
break;
|
||||
}
|
||||
|
||||
const [reasoningContent, content] = parsePart(part, aiChatReasoning);
|
||||
const [reasoningContent, content] = parsePart(part, parseThinkTag);
|
||||
answer += content;
|
||||
reasoning += reasoningContent;
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ import { formatModelChars2Points } from '../../../../support/wallet/usage/utils'
|
||||
import type { SelectedDatasetType } from '@fastgpt/global/core/workflow/api.d';
|
||||
import type { SearchDataResponseItemType } from '@fastgpt/global/core/dataset/type';
|
||||
import type { ModuleDispatchProps } from '@fastgpt/global/core/workflow/runtime/type';
|
||||
import { getEmbeddingModel } from '../../../ai/model';
|
||||
import { getEmbeddingModel, getRerankModel } from '../../../ai/model';
|
||||
import { deepRagSearch, defaultSearchDatasetData } from '../../../dataset/search/controller';
|
||||
import { NodeInputKeyEnum, NodeOutputKeyEnum } from '@fastgpt/global/core/workflow/constants';
|
||||
import { DispatchNodeResponseKeyEnum } from '@fastgpt/global/core/workflow/runtime/constants';
|
||||
@@ -22,9 +22,14 @@ type DatasetSearchProps = ModuleDispatchProps<{
|
||||
[NodeInputKeyEnum.datasetSelectList]: SelectedDatasetType;
|
||||
[NodeInputKeyEnum.datasetSimilarity]: number;
|
||||
[NodeInputKeyEnum.datasetMaxTokens]: number;
|
||||
[NodeInputKeyEnum.datasetSearchMode]: `${DatasetSearchModeEnum}`;
|
||||
[NodeInputKeyEnum.userChatInput]?: string;
|
||||
[NodeInputKeyEnum.datasetSearchMode]: `${DatasetSearchModeEnum}`;
|
||||
[NodeInputKeyEnum.datasetSearchEmbeddingWeight]?: number;
|
||||
|
||||
[NodeInputKeyEnum.datasetSearchUsingReRank]: boolean;
|
||||
[NodeInputKeyEnum.datasetSearchRerankModel]?: string;
|
||||
[NodeInputKeyEnum.datasetSearchRerankWeight]?: number;
|
||||
|
||||
[NodeInputKeyEnum.collectionFilterMatch]: string;
|
||||
[NodeInputKeyEnum.authTmbId]?: boolean;
|
||||
|
||||
@@ -53,11 +58,14 @@ export async function dispatchDatasetSearch(
|
||||
datasets = [],
|
||||
similarity,
|
||||
limit = 1500,
|
||||
usingReRank,
|
||||
searchMode,
|
||||
userChatInput = '',
|
||||
authTmbId = false,
|
||||
collectionFilterMatch,
|
||||
searchMode,
|
||||
embeddingWeight,
|
||||
usingReRank,
|
||||
rerankModel,
|
||||
rerankWeight,
|
||||
|
||||
datasetSearchUsingExtensionQuery,
|
||||
datasetSearchExtensionModel,
|
||||
@@ -122,7 +130,10 @@ export async function dispatchDatasetSearch(
|
||||
limit,
|
||||
datasetIds,
|
||||
searchMode,
|
||||
embeddingWeight,
|
||||
usingReRank: usingReRank && (await checkTeamReRankPermission(teamId)),
|
||||
rerankModel: getRerankModel(rerankModel),
|
||||
rerankWeight,
|
||||
collectionFilterMatch
|
||||
};
|
||||
const {
|
||||
@@ -219,6 +230,9 @@ export async function dispatchDatasetSearch(
|
||||
similarity: usingSimilarityFilter ? similarity : undefined,
|
||||
limit,
|
||||
searchMode,
|
||||
embeddingWeight: searchMode === DatasetSearchModeEnum.mixedRecall ? embeddingWeight : undefined,
|
||||
rerankModel: usingReRank ? getRerankModel(rerankModel)?.name : undefined,
|
||||
rerankWeight: usingReRank ? rerankWeight : undefined,
|
||||
searchUsingReRank: searchUsingReRank,
|
||||
quoteList: searchRes,
|
||||
queryExtensionResult,
|
||||
|
||||
@@ -21,7 +21,7 @@ import {
|
||||
FlowNodeInputTypeEnum,
|
||||
FlowNodeTypeEnum
|
||||
} from '@fastgpt/global/core/workflow/node/constant';
|
||||
import { getNanoid, replaceVariable } from '@fastgpt/global/common/string/tools';
|
||||
import { getNanoid } from '@fastgpt/global/common/string/tools';
|
||||
import { getSystemTime } from '@fastgpt/global/common/time/timezone';
|
||||
|
||||
import { dispatchWorkflowStart } from './init/workflowStart';
|
||||
@@ -426,6 +426,14 @@ export async function dispatchWorkFlow(data: Props): Promise<DispatchFlowRespons
|
||||
})();
|
||||
|
||||
if (!nodeRunResult) return [];
|
||||
if (res?.closed) {
|
||||
addLog.warn('Request is closed', {
|
||||
appId: props.runningAppInfo.id,
|
||||
nodeId: node.nodeId,
|
||||
nodeName: node.name
|
||||
});
|
||||
return [];
|
||||
}
|
||||
|
||||
/*
|
||||
特殊情况:
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
"axios": "^1.8.2",
|
||||
"chalk": "^5.3.0",
|
||||
"cheerio": "1.0.0-rc.12",
|
||||
"cookie": "^0.5.0",
|
||||
"cookie": "^0.7.1",
|
||||
"date-fns": "2.30.0",
|
||||
"dayjs": "^1.11.7",
|
||||
"decompress": "^4.2.1",
|
||||
|
||||
@@ -51,6 +51,9 @@ const OutLinkSchema = new Schema({
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
// showFullText: {
|
||||
// type: Boolean
|
||||
// },
|
||||
showRawSource: {
|
||||
type: Boolean
|
||||
},
|
||||
|
||||
@@ -87,8 +87,7 @@ export async function createDefaultTeam({
|
||||
}) {
|
||||
// auth default team
|
||||
const tmb = await MongoTeamMember.findOne({
|
||||
userId: new Types.ObjectId(userId),
|
||||
defaultTeam: true
|
||||
userId: new Types.ObjectId(userId)
|
||||
});
|
||||
|
||||
if (!tmb) {
|
||||
@@ -113,8 +112,7 @@ export async function createDefaultTeam({
|
||||
name: 'Owner',
|
||||
role: TeamMemberRoleEnum.owner,
|
||||
status: TeamMemberStatusEnum.active,
|
||||
createTime: new Date(),
|
||||
defaultTeam: true
|
||||
createTime: new Date()
|
||||
}
|
||||
],
|
||||
{ session }
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
export const MaxInvitationLinksAmount = 10;
|
||||
49
packages/service/support/user/team/invitationLink/schema.ts
Normal file
@@ -0,0 +1,49 @@
|
||||
import {
|
||||
TeamCollectionName,
|
||||
TeamMemberCollectionName
|
||||
} from '@fastgpt/global/support/user/team/constant';
|
||||
import { connectionMongo, getMongoModel } from '../../../../common/mongo';
|
||||
import { InvitationSchemaType } from './type';
|
||||
import addDays from 'date-fns/esm/fp/addDays/index.js';
|
||||
const { Schema } = connectionMongo;
|
||||
|
||||
export const InvitationCollectionName = 'team_invitation_links';
|
||||
|
||||
const InvitationSchema = new Schema({
|
||||
teamId: {
|
||||
type: Schema.Types.ObjectId,
|
||||
ref: TeamCollectionName,
|
||||
required: true
|
||||
},
|
||||
usedTimesLimit: {
|
||||
type: Number,
|
||||
default: 1,
|
||||
enum: [1, -1]
|
||||
},
|
||||
forbidden: Boolean,
|
||||
expires: Date,
|
||||
description: String,
|
||||
members: {
|
||||
type: [String],
|
||||
default: []
|
||||
}
|
||||
});
|
||||
|
||||
InvitationSchema.virtual('team', {
|
||||
ref: TeamCollectionName,
|
||||
localField: 'teamId',
|
||||
foreignField: '_id',
|
||||
justOne: true
|
||||
});
|
||||
|
||||
try {
|
||||
InvitationSchema.index({ teamId: 1 });
|
||||
InvitationSchema.index({ expires: 1 }, { expireAfterSeconds: 30 * 24 * 60 * 60 });
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
|
||||
export const MongoInvitationLink = getMongoModel<InvitationSchemaType>(
|
||||
InvitationCollectionName,
|
||||
InvitationSchema
|
||||
);
|
||||
37
packages/service/support/user/team/invitationLink/type.ts
Normal file
@@ -0,0 +1,37 @@
|
||||
import { TeamMemberSchema } from '@fastgpt/global/support/user/team/type';
|
||||
|
||||
export type InvitationSchemaType = {
|
||||
_id: string;
|
||||
teamId: string;
|
||||
usedTimesLimit?: number;
|
||||
forbidden?: boolean;
|
||||
expires: Date;
|
||||
description: string;
|
||||
members: string[];
|
||||
};
|
||||
|
||||
export type InvitationType = Omit<InvitationSchemaType, 'members'> & {
|
||||
members: {
|
||||
tmbId: string;
|
||||
avatar: string;
|
||||
name: string;
|
||||
}[];
|
||||
};
|
||||
|
||||
export type InvitationLinkExpiresType = '30m' | '7d' | '1y';
|
||||
|
||||
export type InvitationLinkCreateType = {
|
||||
description: string;
|
||||
expires: InvitationLinkExpiresType;
|
||||
usedTimesLimit: 1 | -1;
|
||||
};
|
||||
export type InvitationLinkUpdateType = Partial<
|
||||
Omit<InvitationSchemaType, 'members' | 'teamId' | '_id'>
|
||||
> & {
|
||||
linkId: string;
|
||||
};
|
||||
|
||||
export type InvitationInfoType = InvitationSchemaType & {
|
||||
teamAvatar: string;
|
||||
teamName: string;
|
||||
};
|
||||
2
packages/service/type.d.ts
vendored
@@ -1,7 +1,7 @@
|
||||
import { FastGPTFeConfigsType, SystemEnvType } from '@fastgpt/global/common/system/types';
|
||||
import {
|
||||
TTSModelType,
|
||||
ReRankModelItemType,
|
||||
RerankModelItemType,
|
||||
STTModelType,
|
||||
EmbeddingModelItemType,
|
||||
LLMModelItemType
|
||||
|
||||
19
packages/web/common/fetch/type.d.ts
vendored
@@ -11,3 +11,22 @@ type PaginationResponse<T = {}> = {
|
||||
total: number;
|
||||
list: T[];
|
||||
};
|
||||
|
||||
type LinkedPaginationProps<T = {}> = T & {
|
||||
pageSize: number;
|
||||
} & RequireOnlyOne<{
|
||||
initialId: string;
|
||||
nextId: string;
|
||||
prevId: string;
|
||||
}> &
|
||||
RequireOnlyOne<{
|
||||
initialIndex: number;
|
||||
nextIndex: number;
|
||||
prevIndex: number;
|
||||
}>;
|
||||
|
||||
type LinkedListResponse<T = {}> = {
|
||||
list: Array<T & { _id: string; index: number }>;
|
||||
hasMorePrev: boolean;
|
||||
hasMoreNext: boolean;
|
||||
};
|
||||
|
||||
@@ -10,15 +10,7 @@ import { Box, Flex } from '@chakra-ui/react';
|
||||
* @param [groupId] - group id to make the key unique
|
||||
* @returns
|
||||
*/
|
||||
function AvatarGroup({
|
||||
avatars,
|
||||
max = 3,
|
||||
groupId
|
||||
}: {
|
||||
max?: number;
|
||||
avatars: string[];
|
||||
groupId?: string;
|
||||
}) {
|
||||
function AvatarGroup({ avatars, max = 3 }: { max?: number; avatars: string[] }) {
|
||||
return (
|
||||
<Flex position="relative">
|
||||
{avatars.slice(0, max).map((avatar, index) => (
|
||||
|
||||
@@ -9,6 +9,7 @@ type Props = FlexProps & {
|
||||
onClick?: () => void;
|
||||
hoverColor?: string;
|
||||
tip?: string;
|
||||
isLoading?: boolean;
|
||||
};
|
||||
|
||||
const MyIconButton = ({
|
||||
@@ -17,11 +18,13 @@ const MyIconButton = ({
|
||||
hoverColor = 'primary.600',
|
||||
size = '1rem',
|
||||
tip,
|
||||
isLoading = false,
|
||||
...props
|
||||
}: Props) => {
|
||||
return (
|
||||
<MyTooltip label={tip}>
|
||||
<Flex
|
||||
position={'relative'}
|
||||
p={1}
|
||||
color={'myGray.500'}
|
||||
rounded={'sm'}
|
||||
@@ -33,10 +36,14 @@ const MyIconButton = ({
|
||||
bg: 'myGray.05',
|
||||
color: hoverColor
|
||||
}}
|
||||
onClick={onClick}
|
||||
onClick={() => {
|
||||
if (isLoading) return;
|
||||
onClick?.();
|
||||
}}
|
||||
sx={{ userSelect: 'none' }}
|
||||
{...props}
|
||||
>
|
||||
<MyIcon name={icon as any} w={size} />
|
||||
<MyIcon name={isLoading ? 'common/loading' : (icon as any)} w={size} />
|
||||
</Flex>
|
||||
</MyTooltip>
|
||||
);
|
||||
|
||||
@@ -35,10 +35,13 @@ export const iconPaths = {
|
||||
'common/dingtalkFill': () => import('./icons/common/dingtalkFill.svg'),
|
||||
'common/disable': () => import('./icons/common/disable.svg'),
|
||||
'common/downArrowFill': () => import('./icons/common/downArrowFill.svg'),
|
||||
'common/download': () => import('./icons/common/download.svg'),
|
||||
'common/edit': () => import('./icons/common/edit.svg'),
|
||||
'common/editor/resizer': () => import('./icons/common/editor/resizer.svg'),
|
||||
'common/enable': () => import('./icons/common/enable.svg'),
|
||||
'common/errorFill': () => import('./icons/common/errorFill.svg'),
|
||||
'common/file/move': () => import('./icons/common/file/move.svg'),
|
||||
'common/fileNotFound': () => import('./icons/common/fileNotFound.svg'),
|
||||
'common/folderFill': () => import('./icons/common/folderFill.svg'),
|
||||
'common/folderImport': () => import('./icons/common/folderImport.svg'),
|
||||
'common/fullScreenLight': () => import('./icons/common/fullScreenLight.svg'),
|
||||
@@ -58,6 +61,8 @@ export const iconPaths = {
|
||||
'common/leftArrowLight': () => import('./icons/common/leftArrowLight.svg'),
|
||||
'common/line': () => import('./icons/common/line.svg'),
|
||||
'common/lineChange': () => import('./icons/common/lineChange.svg'),
|
||||
'common/lineStop': () => import('./icons/common/lineStop.svg'),
|
||||
'common/link': () => import('./icons/common/link.svg'),
|
||||
'common/linkBlue': () => import('./icons/common/linkBlue.svg'),
|
||||
'common/list': () => import('./icons/common/list.svg'),
|
||||
'common/loading': () => import('./icons/common/loading.svg'),
|
||||
@@ -86,7 +91,9 @@ export const iconPaths = {
|
||||
'common/selectLight': () => import('./icons/common/selectLight.svg'),
|
||||
'common/setting': () => import('./icons/common/setting.svg'),
|
||||
'common/settingLight': () => import('./icons/common/settingLight.svg'),
|
||||
'common/solidChevronDown': () => import('./icons/common/solidChevronDown.svg'),
|
||||
'common/solidChevronRight': () => import('./icons/common/solidChevronRight.svg'),
|
||||
'common/solidChevronUp': () => import('./icons/common/solidChevronUp.svg'),
|
||||
'common/subtract': () => import('./icons/common/subtract.svg'),
|
||||
'common/templateMarket': () => import('./icons/common/templateMarket.svg'),
|
||||
'common/text/t': () => import('./icons/common/text/t.svg'),
|
||||
@@ -96,6 +103,7 @@ export const iconPaths = {
|
||||
'common/trash': () => import('./icons/common/trash.svg'),
|
||||
'common/upRightArrowLight': () => import('./icons/common/upRightArrowLight.svg'),
|
||||
'common/uploadFileFill': () => import('./icons/common/uploadFileFill.svg'),
|
||||
'common/upperRight': () => import('./icons/common/upperRight.svg'),
|
||||
'common/userInfo': () => import('./icons/common/userInfo.svg'),
|
||||
'common/variable': () => import('./icons/common/variable.svg'),
|
||||
'common/viewLight': () => import('./icons/common/viewLight.svg'),
|
||||
@@ -204,7 +212,9 @@ export const iconPaths = {
|
||||
'core/dataset/manualCollection': () => import('./icons/core/dataset/manualCollection.svg'),
|
||||
'core/dataset/mixedRecall': () => import('./icons/core/dataset/mixedRecall.svg'),
|
||||
'core/dataset/modeEmbedding': () => import('./icons/core/dataset/modeEmbedding.svg'),
|
||||
'core/dataset/questionExtension': () => import('./icons/core/dataset/questionExtension.svg'),
|
||||
'core/dataset/rerank': () => import('./icons/core/dataset/rerank.svg'),
|
||||
'core/dataset/searchfilter': () => import('./icons/core/dataset/searchfilter.svg'),
|
||||
'core/dataset/splitLight': () => import('./icons/core/dataset/splitLight.svg'),
|
||||
'core/dataset/tableCollection': () => import('./icons/core/dataset/tableCollection.svg'),
|
||||
'core/dataset/tag': () => import('./icons/core/dataset/tag.svg'),
|
||||
@@ -373,9 +383,13 @@ export const iconPaths = {
|
||||
'modal/teamPlans': () => import('./icons/modal/teamPlans.svg'),
|
||||
'model/BAAI': () => import('./icons/model/BAAI.svg'),
|
||||
'model/alicloud': () => import('./icons/model/alicloud.svg'),
|
||||
'model/aws': () => import('./icons/model/aws.svg'),
|
||||
'model/azure': () => import('./icons/model/azure.svg'),
|
||||
'model/baichuan': () => import('./icons/model/baichuan.svg'),
|
||||
'model/chatglm': () => import('./icons/model/chatglm.svg'),
|
||||
'model/claude': () => import('./icons/model/claude.svg'),
|
||||
'model/cloudflare': () => import('./icons/model/cloudflare.svg'),
|
||||
'model/cohere': () => import('./icons/model/cohere.svg'),
|
||||
'model/deepseek': () => import('./icons/model/deepseek.svg'),
|
||||
'model/doubao': () => import('./icons/model/doubao.svg'),
|
||||
'model/ernie': () => import('./icons/model/ernie.svg'),
|
||||
@@ -415,6 +429,7 @@ export const iconPaths = {
|
||||
'price/bg': () => import('./icons/price/bg.svg'),
|
||||
'price/right': () => import('./icons/price/right.svg'),
|
||||
save: () => import('./icons/save.svg'),
|
||||
sliderTag: () => import('./icons/sliderTag.svg'),
|
||||
stop: () => import('./icons/stop.svg'),
|
||||
'support/account/laf': () => import('./icons/support/account/laf.svg'),
|
||||
'support/account/loginoutLight': () => import('./icons/support/account/loginoutLight.svg'),
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" >
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M15.2703 9.04924C15.2703 10.8968 13.8022 12.4015 11.9689 12.4602V12.462H11.7009C11.3327 12.462 11.0342 12.1635 11.0342 11.7953C11.0342 11.4271 11.3327 11.1287 11.7009 11.1287H11.8689C13.0121 11.1226 13.937 10.1939 13.937 9.04924C13.937 8.07583 13.2669 7.25561 12.361 7.03087L11.5956 6.84096L11.3934 6.0787C10.9949 4.57696 9.62484 3.47188 8.00003 3.47188C6.37523 3.47188 5.00513 4.57696 4.60668 6.0787L4.40444 6.84096L3.63901 7.03087C2.73317 7.25561 2.06307 8.07583 2.06307 9.04924C2.06307 10.1977 2.99405 11.1287 4.14248 11.1287L4.14588 11.1286L4.33524 11.1287C4.70343 11.1287 5.00191 11.4271 5.00191 11.7953C5.00191 12.1635 4.70343 12.462 4.33524 12.462H4.14248H4.06858V12.4612C2.2179 12.4219 0.729736 10.9093 0.729736 9.04924C0.729736 7.44874 1.83149 6.10557 3.31794 5.73677C3.86757 3.6652 5.75552 2.13855 8.00003 2.13855C10.2445 2.13855 12.1325 3.6652 12.6821 5.73677C14.1686 6.10557 15.2703 7.44874 15.2703 9.04924ZM8.00002 7.30026C7.63183 7.30026 7.33335 7.59874 7.33335 7.96693V11.8435L6.96682 11.477C6.74816 11.2583 6.39364 11.2583 6.17498 11.477C5.95632 11.6957 5.95632 12.0502 6.17498 12.2688L7.50545 13.5993C7.52049 13.6159 7.53634 13.6318 7.55296 13.6468L7.60322 13.6971C7.82237 13.9162 8.17767 13.9162 8.39682 13.6971L8.44709 13.6468C8.4637 13.6318 8.47955 13.6159 8.49457 13.5993L9.82418 12.2697C10.0433 12.0506 10.0433 11.6953 9.82418 11.4761C9.60503 11.257 9.24973 11.257 9.03058 11.4761L8.66668 11.84V7.96693C8.66668 7.59874 8.36821 7.30026 8.00002 7.30026Z" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.6 KiB |
@@ -0,0 +1,5 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 12 12" fill="none">
|
||||
<path d="M0.246607 10.0893C0.241922 10.0968 0.237518 10.1045 0.23341 10.1124C0.194824 10.1867 0.194824 10.2843 0.194824 10.4795V10.7803C0.194824 10.9755 0.194824 11.0731 0.23341 11.1473C0.265926 11.2099 0.316964 11.261 0.37956 11.2935C0.453841 11.3321 0.55143 11.3321 0.746607 11.3321H1.04222C1.20929 11.3321 1.30485 11.3321 1.3755 11.3079C1.38016 11.3066 1.38481 11.3052 1.38944 11.3037C1.50916 11.2658 1.61267 11.1623 1.81968 10.9553L8.4032 4.37179L7.15796 3.12655L0.574444 9.71007C0.397236 9.88728 0.29587 9.98864 0.246607 10.0893Z" />
|
||||
<path d="M9.43317 3.34182L8.18793 2.09658L9.34895 0.935566C9.36436 0.920152 9.37233 0.912183 9.37902 0.905775C9.71036 0.588537 10.2328 0.588537 10.5641 0.905775C10.5708 0.91219 10.5786 0.919938 10.594 0.935383L10.5946 0.935931C10.6099 0.951255 10.6176 0.958969 10.624 0.965642C10.9412 1.29698 10.9412 1.81939 10.624 2.15073C10.6175 2.15745 10.6098 2.16524 10.5942 2.1808L9.43317 3.34182Z" />
|
||||
<path d="M4.47921 10.6383C4.47921 10.2552 4.78981 9.9446 5.17296 9.9446H11.1114C11.4946 9.9446 11.8052 10.2552 11.8052 10.6383C11.8052 11.0215 11.4946 11.3321 11.1114 11.3321H5.17296C4.78981 11.3321 4.47921 11.0215 4.47921 10.6383Z" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.2 KiB |
@@ -0,0 +1,7 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32" fill="none">
|
||||
<path d="M4 5H26V10H4V5Z" fill="#ECECEC"/>
|
||||
<path d="M4 12H26V17H4V12Z" fill="#ECECEC"/>
|
||||
<path d="M4 19H26V24H4V19Z" fill="#ECECEC"/>
|
||||
<path d="M21.8982 27.7967C18.0945 27.7967 15 24.7021 15 20.8983C15 17.0947 18.0945 14 21.8982 14C25.7019 14 28.7965 17.0947 28.7965 20.8983C28.7965 24.702 25.7019 27.7967 21.8982 27.7967ZM21.8982 15.698C19.0307 15.698 16.698 18.0309 16.698 20.8983C16.698 23.7658 19.0307 26.0988 21.8982 26.0988C24.7657 26.0988 27.0986 23.7658 27.0986 20.8983C27.0986 18.0309 24.7657 15.698 21.8982 15.698Z" fill="#BEC2C9"/>
|
||||
<path d="M29.9551 30C29.6876 30 29.4203 29.8979 29.2162 29.694L25.6122 26.0902C25.2042 25.6821 25.2042 25.0205 25.6122 24.6124C26.0204 24.2044 26.6819 24.2044 27.09 24.6124L30.694 28.2162C31.102 28.6242 31.102 29.2859 30.694 29.694C30.4899 29.8979 30.2225 30 29.9551 30Z" fill="#BEC2C9"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 942 B |
@@ -0,0 +1,10 @@
|
||||
<svg width="17" height="16" viewBox="0 0 17 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<g clip-path="url(#clip0_17994_4)">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M8.98584 2.23348C5.80108 2.23348 3.21932 4.81524 3.21932 8C3.21932 11.1848 5.80108 13.7665 8.98584 13.7665C12.1706 13.7665 14.7524 11.1848 14.7524 8C14.7524 4.81524 12.1706 2.23348 8.98584 2.23348ZM1.93787 8C1.93787 4.10751 5.09335 0.952026 8.98584 0.952026C12.8783 0.952026 16.0338 4.10751 16.0338 8C16.0338 11.8925 12.8783 15.048 8.98584 15.048C5.09335 15.048 1.93787 11.8925 1.93787 8ZM6.42294 6.07782C6.42294 5.72396 6.7098 5.4371 7.06366 5.4371H10.908C11.2619 5.4371 11.5487 5.72396 11.5487 6.07782V9.92217C11.5487 10.276 11.2619 10.5629 10.908 10.5629H7.06366C6.7098 10.5629 6.42294 10.276 6.42294 9.92217V6.07782ZM7.70439 6.71855V9.28145H10.2673V6.71855H7.70439Z" fill="#485264"/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_17994_4">
|
||||
<rect width="16" height="16" fill="white" transform="translate(0.98584)"/>
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1013 B |
@@ -0,0 +1,3 @@
|
||||
<svg width="17" height="16" viewBox="0 0 17 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M8.98608 2.34313C10.5482 0.78103 13.0808 0.78103 14.6429 2.34313C16.205 3.90522 16.205 6.43788 14.6429 7.99998L13.7001 8.94279C13.4398 9.20314 13.0177 9.20314 12.7573 8.94279C12.497 8.68244 12.497 8.26033 12.7573 7.99998L13.7001 7.05717C14.7415 6.01577 14.7415 4.32733 13.7001 3.28594C12.6587 2.24454 10.9703 2.24454 9.92889 3.28594L8.98608 4.22875C8.72573 4.48909 8.30362 4.48909 8.04327 4.22875C7.78292 3.9684 7.78292 3.54629 8.04327 3.28594L8.98608 2.34313ZM11.7908 5.19523C12.0512 5.45558 12.0512 5.87769 11.7908 6.13804L7.12415 10.8047C6.8638 11.0651 6.44169 11.0651 6.18134 10.8047C5.92099 10.5444 5.92099 10.1222 6.18134 9.8619L10.848 5.19523C11.1084 4.93488 11.5305 4.93488 11.7908 5.19523ZM5.21484 7.05717C5.47519 7.31752 5.47519 7.73963 5.21484 7.99998L4.27204 8.94279C3.23064 9.98419 3.23064 11.6726 4.27204 12.714C5.31343 13.7554 7.00187 13.7554 8.04327 12.714L8.98608 11.7712C9.24643 11.5109 9.66854 11.5109 9.92889 11.7712C10.1892 12.0316 10.1892 12.4537 9.92889 12.714L8.98608 13.6568C7.42398 15.2189 4.89132 15.2189 3.32923 13.6568C1.76713 12.0947 1.76713 9.56208 3.32923 7.99998L4.27204 7.05717C4.53239 6.79682 4.9545 6.79682 5.21484 7.05717Z" fill="#485264"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.3 KiB |
@@ -0,0 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 19 18" fill="none">
|
||||
<path d="M13.4032 6C14.7396 6 15.4088 7.61571 14.4639 8.56066L10.6388 12.3858C10.053 12.9715 9.10324 12.9715 8.51745 12.3858L4.69235 8.56066C3.7474 7.61571 4.41665 6 5.75301 6H13.4032Z" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 270 B |
@@ -0,0 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 19 18" fill="none">
|
||||
<path d="M13.4032 12.0751C14.7396 12.0751 15.4088 10.4594 14.4639 9.51441L10.6388 5.68931C10.053 5.10352 9.10324 5.10352 8.51745 5.68931L4.69235 9.51441C3.7474 10.4594 4.41665 12.0751 5.75301 12.0751H13.4032Z" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 294 B |
@@ -0,0 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="none">
|
||||
<path d="M5.44766 4.22876C5.44765 4.59695 5.74613 4.89542 6.11432 4.89542L10.1617 4.89542L3.7573 11.2998C3.49695 11.5602 3.49695 11.9823 3.7573 12.2426C4.01765 12.503 4.43976 12.503 4.70011 12.2426L11.1045 5.83823L11.1045 9.88561C11.1045 10.2538 11.403 10.5523 11.7712 10.5523C12.1394 10.5523 12.4378 10.2538 12.4378 9.88561L12.4378 4.22876C12.4378 3.86057 12.1394 3.56209 11.7712 3.56209L6.11432 3.56209C5.74613 3.56209 5.44765 3.86057 5.44766 4.22876Z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 539 B |
@@ -1,3 +1,3 @@
|
||||
<svg viewBox="0 0 19 18" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M4.237 6.21967C4.5299 5.92678 5.00477 5.92678 5.29766 6.21967L9.26733 10.1893L13.237 6.21967C13.5299 5.92678 14.0048 5.92678 14.2977 6.21967C14.5906 6.51256 14.5906 6.98744 14.2977 7.28033L9.79766 11.7803C9.50477 12.0732 9.0299 12.0732 8.737 11.7803L4.237 7.28033C3.94411 6.98744 3.94411 6.51256 4.237 6.21967Z" />
|
||||
</svg>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" >
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M3.52858 5.52876C3.78892 5.26841 4.21103 5.26841 4.47138 5.52876L7.99998 9.05735L11.5286 5.52876C11.7889 5.26841 12.211 5.26841 12.4714 5.52876C12.7317 5.78911 12.7317 6.21122 12.4714 6.47157L8.47138 10.4716C8.21103 10.7319 7.78892 10.7319 7.52858 10.4716L3.52858 6.47157C3.26823 6.21122 3.26823 5.78911 3.52858 5.52876Z" />
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 444 B After Width: | Height: | Size: 445 B |
@@ -1,3 +1,3 @@
|
||||
<svg viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M3.96967 11.7803C4.26256 12.0732 4.73744 12.0732 5.03033 11.7803L9 7.81066L12.9697 11.7803C13.2626 12.0732 13.7374 12.0732 14.0303 11.7803C14.3232 11.4874 14.3232 11.0126 14.0303 10.7197L9.53033 6.21967C9.23744 5.92678 8.76256 5.92678 8.46967 6.21967L3.96967 10.7197C3.67678 11.0126 3.67678 11.4874 3.96967 11.7803Z" />
|
||||
</svg>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" >
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M3.52858 10.4712C3.78892 10.7316 4.21103 10.7316 4.47138 10.4712L7.99998 6.94265L11.5286 10.4712C11.7889 10.7316 12.211 10.7316 12.4714 10.4712C12.7317 10.2109 12.7317 9.78878 12.4714 9.52843L8.47138 5.52843C8.21103 5.26808 7.78892 5.26808 7.52858 5.52843L3.52858 9.52843C3.26823 9.78878 3.26823 10.2109 3.52858 10.4712Z" />
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 449 B After Width: | Height: | Size: 445 B |
@@ -1 +1,3 @@
|
||||
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1698497259520" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="10081" xmlns:xlink="http://www.w3.org/1999/xlink" width="128" height="128"><path d="M156.09136 606.57001a457.596822 457.596822 0 0 1 221.680239-392.516385 50.844091 50.844091 0 1 1 50.844091 86.943396 355.90864 355.90864 0 0 0-138.804369 152.532274h16.77855a152.532274 152.532274 0 1 1-152.532274 152.532274z m406.752731 0a457.596822 457.596822 0 0 1 221.680239-392.007944 50.844091 50.844091 0 1 1 50.844091 86.943396 355.90864 355.90864 0 0 0-138.804369 152.532274h16.77855a152.532274 152.532274 0 1 1-152.532274 152.532274z" fill="#E67E22" p-id="10082"></path></svg>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none">
|
||||
<path d="M11.2308 13.6099V18.2252C11.2308 18.8663 11.0064 19.4111 10.5577 19.8599C10.109 20.3086 9.5641 20.5329 8.92307 20.5329H4.30769C3.66667 20.5329 3.12179 20.3086 2.67308 19.8599C2.22436 19.4111 2 18.8663 2 18.2252V9.76371C2 8.93038 2.16226 8.1351 2.48678 7.37789C2.8113 6.62068 3.25 5.96563 3.80288 5.41275C4.35577 4.85986 5.01082 4.42116 5.76803 4.09664C6.52524 3.77212 7.32051 3.60986 8.15384 3.60986H8.92307C9.13141 3.60986 9.3117 3.68598 9.46394 3.83823C9.61618 3.99047 9.6923 4.17076 9.6923 4.37909V5.91756C9.6923 6.12589 9.61618 6.30618 9.46394 6.45842C9.3117 6.61066 9.13141 6.68679 8.92307 6.68679H8.15384C7.30448 6.68679 6.57933 6.98727 5.97836 7.58823C5.3774 8.18919 5.07692 8.91435 5.07692 9.76371V10.1483C5.07692 10.4688 5.1891 10.7413 5.41346 10.9656C5.63782 11.19 5.91025 11.3022 6.23077 11.3022H8.92307C9.5641 11.3022 10.109 11.5265 10.5577 11.9752C11.0064 12.424 11.2308 12.9688 11.2308 13.6099ZM22 13.6099V18.2252C22 18.8663 21.7756 19.4111 21.3269 19.8599C20.8782 20.3086 20.3333 20.5329 19.6923 20.5329H15.0769C14.4359 20.5329 13.891 20.3086 13.4423 19.8599C12.9936 19.4111 12.7692 18.8663 12.7692 18.2252V9.76371C12.7692 8.93038 12.9315 8.1351 13.256 7.37789C13.5805 6.62068 14.0192 5.96563 14.5721 5.41275C15.125 4.85986 15.78 4.42116 16.5373 4.09664C17.2945 3.77212 18.0897 3.60986 18.9231 3.60986H19.6923C19.9006 3.60986 20.0809 3.68598 20.2332 3.83823C20.3854 3.99047 20.4615 4.17076 20.4615 4.37909V5.91756C20.4615 6.12589 20.3854 6.30618 20.2332 6.45842C20.0809 6.61066 19.9006 6.68679 19.6923 6.68679H18.9231C18.0737 6.68679 17.3486 6.98727 16.7476 7.58823C16.1466 8.18919 15.8461 8.91435 15.8461 9.76371V10.1483C15.8461 10.4688 15.9583 10.7413 16.1827 10.9656C16.407 11.19 16.6795 11.3022 17 11.3022H19.6923C20.3333 11.3022 20.8782 11.5265 21.3269 11.9752C21.7756 12.424 22 12.9688 22 13.6099Z" />
|
||||
</svg>
|
||||
|
Before Width: | Height: | Size: 819 B After Width: | Height: | Size: 1.9 KiB |
@@ -0,0 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 17 16" >
|
||||
<path d="M11.3317 4.63043L12.3128 5.61147L8.98815 8.9361L6.74675 6.6947C6.68372 6.63154 6.60886 6.58144 6.52644 6.54725C6.44402 6.51306 6.35567 6.49546 6.26645 6.49546C6.17722 6.49546 6.08887 6.51306 6.00646 6.54725C5.92404 6.58144 5.84918 6.63154 5.78615 6.6947L1.69849 10.7892C1.63542 10.8522 1.58538 10.9271 1.55125 11.0095C1.51711 11.0919 1.49954 11.1803 1.49954 11.2695C1.49954 11.3587 1.51711 11.447 1.55125 11.5294C1.58538 11.6118 1.63542 11.6867 1.69849 11.7498C1.76156 11.8128 1.83644 11.8629 1.91885 11.897C2.00126 11.9312 2.08959 11.9487 2.17879 11.9487C2.26799 11.9487 2.35632 11.9312 2.43873 11.897C2.52114 11.8629 2.59601 11.8128 2.65909 11.7498L6.26304 8.13901L8.50444 10.3804C8.77014 10.6461 9.19934 10.6461 9.46504 10.3804L13.2734 6.57888L14.2544 7.55992C14.302 7.6066 14.3623 7.63828 14.4277 7.65104C14.4932 7.66379 14.5609 7.65706 14.6226 7.63167C14.6842 7.60628 14.7371 7.56336 14.7746 7.50822C14.8121 7.45308 14.8326 7.38815 14.8335 7.32147V4.39198C14.8354 4.34733 14.8281 4.30276 14.812 4.26104C14.796 4.21931 14.7716 4.18132 14.7403 4.1494C14.709 4.11747 14.6716 4.0923 14.6302 4.07544C14.5888 4.05858 14.5444 4.05038 14.4997 4.05135H11.577C11.5097 4.05095 11.4439 4.07047 11.3877 4.10745C11.3315 4.14443 11.2876 4.1972 11.2613 4.25913C11.2351 4.32106 11.2278 4.38937 11.2403 4.45544C11.2529 4.52152 11.2847 4.5824 11.3317 4.63043Z" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.4 KiB |
@@ -0,0 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 17 16" >
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M13.8911 3.61032C15.0171 5.17598 14.8761 7.37117 13.4681 8.77915L12.6427 9.60456C12.3733 9.87396 11.9365 9.87396 11.6671 9.60456L6.97652 4.91394C6.70711 4.64454 6.70711 4.20775 6.97652 3.93834L7.80192 3.11294C9.20207 1.71279 11.3807 1.56556 12.9446 2.67127L13.8718 1.74404C14.1322 1.48369 14.5543 1.48369 14.8146 1.74404C15.075 2.00439 15.075 2.4265 14.8146 2.68685L13.8911 3.61032ZM2.18142 13.4425C1.92107 13.7029 1.92107 14.125 2.18142 14.3853C2.44177 14.6457 2.86388 14.6457 3.12423 14.3853L4.04283 13.4667C5.6079 14.5859 7.79751 14.4428 9.20286 13.0374L10.0283 12.212C10.2977 11.9426 10.2977 11.5058 10.0283 11.2364L9.44649 10.6546L9.94334 10.1578C10.2037 9.89744 10.2037 9.47533 9.94334 9.21498C9.68299 8.95463 9.26088 8.95463 9.00053 9.21498L8.50368 9.71183L6.87902 8.08717L7.37233 7.59386C7.63268 7.33351 7.63268 6.9114 7.37233 6.65105C7.11198 6.3907 6.68987 6.3907 6.42952 6.65105L5.93621 7.14436L5.33765 6.5458C5.06824 6.27639 4.63145 6.27639 4.36205 6.5458L3.53665 7.3712C2.13385 8.774 1.98872 10.9582 3.10124 12.5227L2.18142 13.4425ZM4.84985 7.94362L4.47946 8.31401C3.43548 9.35799 3.43548 11.0506 4.47946 12.0946C5.52344 13.1386 7.21607 13.1386 8.26005 12.0946L8.63044 11.7242L4.84985 7.94362ZM12.5253 7.83635L12.1549 8.20674L8.37433 4.42614L8.74473 4.05575C9.78871 3.01177 11.4813 3.01177 12.5253 4.05575C13.5693 5.09973 13.5693 6.79236 12.5253 7.83635Z" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.5 KiB |
1
packages/web/components/common/Icon/icons/model/aws.svg
Normal file
@@ -0,0 +1 @@
|
||||
<svg t="1741332650600" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="6423" width="64" height="64"><path d="M288.695 427.886c0 12.653 1.316 22.893 3.73 30.427 2.706 7.534 6.144 15.726 10.972 24.576a14.848 14.848 0 0 1 2.34 7.9c0 3.364-2.048 6.802-6.51 10.24l-21.43 14.336a16.31 16.31 0 0 1-8.85 3.072c-3.438 0-6.803-1.683-10.24-4.755a105.618 105.618 0 0 1-12.289-16.091 263.607 263.607 0 0 1-10.532-20.114c-26.551 31.451-59.977 47.104-100.206 47.104-28.526 0-51.42-8.192-68.023-24.576-16.75-16.384-25.307-38.254-25.307-65.61 0-29.11 10.24-52.662 31.012-70.436s48.42-26.697 83.456-26.697c11.63 0 23.552 1.024 36.133 2.78 12.58 1.681 25.6 4.388 39.204 7.533V322.56c0-26.039-5.485-44.105-16.091-54.71-10.825-10.607-29.257-15.727-55.442-15.727-11.923 0-24.21 1.39-36.791 4.389a269.897 269.897 0 0 0-36.791 11.703 97.573 97.573 0 0 1-11.922 4.388 20.7 20.7 0 0 1-5.486 1.024c-4.754 0-7.168-3.364-7.168-10.605v-16.53c0-5.486 0.731-9.582 2.414-11.996a25.454 25.454 0 0 1 9.508-7.168c11.923-6.144 26.259-11.337 42.935-15.36 16.677-4.462 34.377-6.583 53.175-6.583 40.521 0 70.217 9.29 89.234 27.794 18.725 18.36 28.307 46.446 28.307 84.042v110.665h0.658z m-138.313 51.931c11.264 0 22.82-2.048 35.108-6.144 12.215-4.096 23.113-11.63 32.33-21.87a54.272 54.272 0 0 0 11.63-21.942 122.88 122.88 0 0 0 3.364-29.696v-14.336a255.927 255.927 0 0 0-63.342-7.9c-22.82 0-39.497 4.462-50.761 13.751-11.264 9.216-16.677 22.162-16.677 39.278 0 16.091 4.023 28.013 12.58 36.205 8.193 8.558 20.115 12.654 35.768 12.654z m273.554 36.937c-6.144 0-10.24-1.024-12.946-3.437-2.707-2.048-5.12-6.803-7.168-13.312l-80.019-264.192a59.83 59.83 0 0 1-3.072-13.678c0-5.486 2.707-8.558 8.12-8.558h33.426c6.436 0 10.898 1.024 13.312 3.438 2.706 2.048 4.754 6.802 6.802 13.312l57.198 226.23 53.174-226.23c1.683-6.876 3.73-11.264 6.437-13.312a23.406 23.406 0 0 1 13.605-3.438h27.282c6.51 0 10.971 1.024 13.604 3.438 2.78 2.048 5.12 6.802 6.51 13.312l53.833 228.937 58.953-228.937a29.403 29.403 0 0 1 6.803-13.312 22.235 22.235 0 0 1 13.239-3.438h31.744c5.412 0 8.484 2.706 8.484 8.558 0 1.682-0.366 3.364-0.731 5.412a50.103 50.103 0 0 1-2.34 8.558L648.118 500.37c-2.048 6.803-4.389 11.264-7.168 13.312a21.723 21.723 0 0 1-12.946 3.438h-29.258c-6.582 0-10.971-1.024-13.677-3.438-2.707-2.413-5.12-6.875-6.437-13.677l-52.809-220.453-52.517 220.16c-1.682 6.802-3.73 11.19-6.436 13.605s-7.534 3.437-13.605 3.437h-29.33z m437.76 9.216c-17.7 0-35.401-2.048-52.443-6.144a155.063 155.063 0 0 1-39.205-13.677c-5.413-3.072-9.216-6.51-10.533-9.509a24.137 24.137 0 0 1-2.048-9.655v-17.408c0-7.168 2.707-10.606 7.827-10.606 2.048 0 4.096 0.366 6.144 1.024 2.048 0.732 5.12 2.048 8.484 3.438a188.428 188.428 0 0 0 37.45 11.996c13.677 2.706 26.99 4.096 40.594 4.096 21.43 0 38.107-3.804 49.737-11.264a36.937 36.937 0 0 0 17.7-32.549 33.353 33.353 0 0 0-9.216-23.918c-6.144-6.51-17.7-12.288-34.377-17.773l-49.444-15.36c-24.869-7.9-43.228-19.456-54.492-34.89a81.554 81.554 0 0 1-7.826-87.478 87.771 87.771 0 0 1 24.503-28.014c10.24-7.9 21.87-13.678 35.474-17.774 13.605-4.096 27.94-5.851 42.935-5.851 7.46 0 15.36 0.365 22.82 1.39 7.827 1.023 14.995 2.413 22.09 3.73 6.875 1.755 13.312 3.437 19.456 5.485 6.144 2.048 10.898 4.096 14.336 6.144a29.477 29.477 0 0 1 10.24 8.558 18.432 18.432 0 0 1 2.999 11.264v16.092c0 7.168-2.707 10.971-7.827 10.971a35.109 35.109 0 0 1-12.946-4.17 155.502 155.502 0 0 0-65.39-13.311c-19.456 0-34.743 3.072-45.348 9.582-10.533 6.51-16.019 16.384-16.019 30.427 0 9.509 3.438 17.774 10.24 24.283 6.803 6.51 19.456 12.947 37.523 18.798l48.347 15.36c24.503 7.9 42.204 18.798 52.81 32.841 10.532 13.97 15.652 30.062 15.652 47.836 0 14.701-3.072 28.013-8.777 39.643-6.071 11.703-14.629 21.943-24.942 30.062a109.714 109.714 0 0 1-37.815 19.163c-15.36 4.755-31.305 7.168-48.713 7.168z" fill="#252F3E" p-id="6424"></path><path d="M926.062 692.15C814.08 775.169 651.118 819.2 511.122 819.2c-196.242 0-373.028-72.777-506.587-193.829-10.533-9.508-1.024-22.528 11.63-14.994C160.549 694.491 338.725 745.4 523.045 745.4c124.342 0 260.973-26.039 386.706-79.36 18.724-8.485 34.743 12.361 16.31 26.039z" fill="#FF9900" p-id="6425"></path><path d="M972.8 638.757c-14.336-18.432-94.793-8.85-131.218-4.389-10.972 1.317-12.58-8.265-2.707-15.36 64-45.202 169.326-32.183 181.541-17.115 12.288 15.36-3.365 120.978-63.342 171.593-9.216 7.826-18.066 3.73-13.97-6.583 13.605-33.792 43.886-110.007 29.623-128.146z" fill="#FF9900" p-id="6426"></path></svg>
|
||||
|
After Width: | Height: | Size: 4.3 KiB |
@@ -0,0 +1 @@
|
||||
<svg t="1741332590124" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2637" width="64" height="64"><path d="M384.032 128h227.264l-235.904 741.792a36.48 36.48 0 0 1-34.336 26.208H164.16A37.312 37.312 0 0 1 128 857.632a41.6 41.6 0 0 1 1.92-12.32l219.84-691.168A36.48 36.48 0 0 1 384.032 128" fill="#01579B" p-id="2638"></path><path d="M714.24 640H353.92a17.184 17.184 0 0 0-16.704 17.6 18.24 18.24 0 0 0 5.312 13.056l231.552 214.912a35.2 35.2 0 0 0 24.8 10.4h204.032z" fill="#1976D2" p-id="2639"></path><path d="M674.272 154.112A36.48 36.48 0 0 0 640.032 128h-253.28a36.48 36.48 0 0 1 34.304 26.08l219.776 691.168a39.04 39.04 0 0 1-22.72 48.64 35.2 35.2 0 0 1-11.584 2.048h253.28A37.312 37.312 0 0 0 896 857.6a41.6 41.6 0 0 0-1.92-12.32L674.304 154.144z" fill="#29B6F6" p-id="2640"></path></svg>
|
||||
|
After Width: | Height: | Size: 838 B |
@@ -0,0 +1 @@
|
||||
<svg t="1741333125459" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="11365" width="64" height="64"><path d="M704.38432 718.72c6.304-21.632 3.872-41.408-6.624-56.128-9.568-13.504-25.792-21.28-45.28-22.208l-369.472-4.8h-0.096a6.688 6.688 0 0 1-5.568-3.008l-0.032-0.032a8.192 8.192 0 0 1-0.896-6.624 10.24 10.24 0 0 1 8.672-6.656l372.736-4.8c44.16-2.08 92.16-37.824 108.96-81.632l21.28-55.52a11.584 11.584 0 0 0 0.64-7.168 242.4 242.4 0 0 0-236.8-189.664 242.656 242.656 0 0 0-229.856 164.768 110.176 110.176 0 0 0-76.544-21.28 109.28 109.28 0 0 0-94.816 135.648 155.04 155.04 0 0 0-150.656 155.168c0 7.456 0.608 15.008 1.504 22.496a7.456 7.456 0 0 0 7.2 6.304h681.888a9.312 9.312 0 0 0 8.672-6.624l5.12-18.208z m117.6-237.376c-3.296 0-6.88 0-10.176 0.48-2.4 0-4.512 1.76-5.408 4.16l-14.4 50.112c-6.304 21.632-3.904 41.408 6.592 56.16 9.632 13.504 25.824 21.248 45.344 22.176l78.656 4.832c2.368 0 4.512 1.12 5.664 3.008a8.64 8.64 0 0 1 0.928 6.656 10.24 10.24 0 0 1-8.704 6.624l-81.952 4.8c-44.416 2.08-92.096 37.824-108.928 81.664l-5.984 15.296c-1.216 3.04 0.928 6.048 4.192 6.048h281.504a7.36 7.36 0 0 0 7.2-5.376c4.8-17.408 7.488-35.712 7.488-54.624 0-111.04-90.656-201.696-202.016-201.696z" fill="#F38020" p-id="11366"></path></svg>
|
||||
|
After Width: | Height: | Size: 1.2 KiB |
@@ -0,0 +1 @@
|
||||
<svg t="1741332939210" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="7576" width="64" height="64"><path d="M331.712601 609.625898c27.560944 0 82.426848-1.535904 158.112785-32.723288 88.31448-36.349728 264.004833-102.3936 390.716913-170.144032 88.655792-47.35704 127.480032-110.158448 127.480033-194.547841A212.168073 212.168073 0 0 0 795.811595 0H304.791617A304.791617 304.791617 0 0 0 0 304.791617c0 168.309481 127.736016 304.834281 331.712601 304.834281z" fill="#39594D" p-id="7577"></path><path d="M414.736746 819.490115a204.147241 204.147241 0 0 1 125.8588-188.574881l154.699665-64.166656c156.406225-64.84928 328.598129 50.044872 328.598129 219.420953a237.510489 237.510489 0 0 1-237.638481 237.510489h-167.413537a204.147241 204.147241 0 0 1-204.104576-204.189905z" fill="#D18EE2" p-id="7578"></path><path d="M175.690353 649.772723A175.690353 175.690353 0 0 0 0 825.548403v22.739912a175.690353 175.690353 0 0 0 351.423369 0v-22.739912a175.690353 175.690353 0 0 0-175.733016-175.690352z" fill="#FF7759" p-id="7579"></path></svg>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
3
packages/web/components/common/Icon/icons/sliderTag.svg
Normal file
@@ -0,0 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 11 11" >
|
||||
<path d="M5.04123 0.144501L9.47821 4.82132C9.83075 5.19292 10.0273 5.68562 10.0273 6.19784V8.65565C10.0273 9.76022 9.13185 10.6557 8.02728 10.6557H2.05518C0.950606 10.6557 0.0551758 9.76022 0.0551758 8.65565V6.19785C0.0551758 5.68562 0.251705 5.19292 0.604247 4.82132L5.04123 0.144501Z" fill="#3370FF"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 375 B |
@@ -53,6 +53,7 @@ const MyModal = ({
|
||||
allowPinchZoom
|
||||
scrollBehavior={'inside'}
|
||||
closeOnOverlayClick={closeOnOverlayClick}
|
||||
returnFocusOnClose={false}
|
||||
>
|
||||
<ModalOverlay />
|
||||
<ModalContent
|
||||
|
||||
@@ -24,6 +24,7 @@ import MyIcon from '../Icon';
|
||||
import { useRequest2 } from '../../../hooks/useRequest';
|
||||
import MyDivider from '../MyDivider';
|
||||
import { useScrollPagination } from '../../../hooks/useScrollPagination';
|
||||
import Avatar from '../Avatar';
|
||||
|
||||
/** 选择组件 Props 类型
|
||||
* value: 选中的值
|
||||
@@ -32,20 +33,21 @@ import { useScrollPagination } from '../../../hooks/useScrollPagination';
|
||||
* isLoading: 是否加载中
|
||||
* ScrollData: 分页滚动数据控制器 [useScrollPagination] 的返回值
|
||||
* */
|
||||
export type SelectProps<T = any> = ButtonProps & {
|
||||
export type SelectProps<T = any> = Omit<ButtonProps, 'onChange'> & {
|
||||
value?: T;
|
||||
placeholder?: string;
|
||||
isSearch?: boolean;
|
||||
list: {
|
||||
alias?: string;
|
||||
icon?: string;
|
||||
iconSize?: string;
|
||||
label: string | React.ReactNode;
|
||||
description?: string;
|
||||
value: T;
|
||||
showBorder?: boolean;
|
||||
}[];
|
||||
isLoading?: boolean;
|
||||
onchange?: (val: T) => any | Promise<any>;
|
||||
onChange?: (val: T) => any | Promise<any>;
|
||||
ScrollData?: ReturnType<typeof useScrollPagination>['ScrollData'];
|
||||
};
|
||||
|
||||
@@ -56,7 +58,7 @@ const MySelect = <T = any,>(
|
||||
isSearch = false,
|
||||
width = '100%',
|
||||
list = [],
|
||||
onchange,
|
||||
onChange,
|
||||
isLoading = false,
|
||||
ScrollData,
|
||||
...props
|
||||
@@ -115,7 +117,7 @@ const MySelect = <T = any,>(
|
||||
}
|
||||
}, [isSearch, isOpen]);
|
||||
|
||||
const { runAsync: onChange, loading } = useRequest2((val: T) => onchange?.(val));
|
||||
const { runAsync: onclickChange, loading } = useRequest2((val: T) => onChange?.(val));
|
||||
|
||||
const ListRender = useMemo(() => {
|
||||
return (
|
||||
@@ -135,16 +137,17 @@ const MySelect = <T = any,>(
|
||||
color: 'myGray.900'
|
||||
})}
|
||||
onClick={() => {
|
||||
if (onChange && value !== item.value) {
|
||||
onChange(item.value);
|
||||
if (value !== item.value) {
|
||||
onclickChange(item.value);
|
||||
}
|
||||
}}
|
||||
whiteSpace={'pre-wrap'}
|
||||
fontSize={'sm'}
|
||||
display={'block'}
|
||||
mb={0.5}
|
||||
>
|
||||
<Flex alignItems={'center'}>
|
||||
{item.icon && <MyIcon mr={2} name={item.icon as any} w={'1rem'} />}
|
||||
{item.icon && <Avatar mr={2} src={item.icon as any} w={item.iconSize ?? '1rem'} />}
|
||||
{item.label}
|
||||
</Flex>
|
||||
{item.description && (
|
||||
@@ -224,7 +227,9 @@ const MySelect = <T = any,>(
|
||||
/>
|
||||
) : (
|
||||
<>
|
||||
{selectItem?.icon && <MyIcon mr={2} name={selectItem.icon as any} w={'1rem'} />}
|
||||
{selectItem?.icon && (
|
||||
<Avatar mr={2} src={selectItem.icon as any} w={selectItem.iconSize ?? '1rem'} />
|
||||
)}
|
||||
{selectItem?.alias || selectItem?.label || placeholder}
|
||||
</>
|
||||
)}
|
||||
|
||||
@@ -73,6 +73,11 @@ const LightRowTabs = <ValueType = string,>({
|
||||
color: activeColor
|
||||
}}
|
||||
fontWeight={'medium'}
|
||||
onClick={() => {
|
||||
if (value === item.value) return;
|
||||
onChange(item.value);
|
||||
}}
|
||||
{...inlineStyles}
|
||||
{...(value === item.value
|
||||
? {
|
||||
color: activeColor,
|
||||
@@ -82,11 +87,6 @@ const LightRowTabs = <ValueType = string,>({
|
||||
: {
|
||||
cursor: 'pointer'
|
||||
})}
|
||||
onClick={() => {
|
||||
if (value === item.value) return;
|
||||
onChange(item.value);
|
||||
}}
|
||||
{...inlineStyles}
|
||||
>
|
||||
{item.icon && (
|
||||
<>
|
||||
|
||||
239
packages/web/hooks/useLinkedScroll.tsx
Normal file
@@ -0,0 +1,239 @@
|
||||
import { useEffect, useRef, useState, ReactNode } from 'react';
|
||||
import { LinkedListResponse, LinkedPaginationProps } from '../common/fetch/type';
|
||||
import { Box, BoxProps } from '@chakra-ui/react';
|
||||
import { useTranslation } from 'next-i18next';
|
||||
import { useScroll, useMemoizedFn, useDebounceEffect } from 'ahooks';
|
||||
import MyBox from '../components/common/MyBox';
|
||||
import { useRequest2 } from './useRequest';
|
||||
import { delay } from '../../global/common/system/utils';
|
||||
|
||||
const threshold = 100;
|
||||
|
||||
export function useLinkedScroll<
|
||||
TParams extends LinkedPaginationProps & { isInitialLoad?: boolean },
|
||||
TData extends LinkedListResponse
|
||||
>(
|
||||
api: (data: TParams) => Promise<TData>,
|
||||
{
|
||||
pageSize = 15,
|
||||
params = {},
|
||||
currentData
|
||||
}: {
|
||||
pageSize?: number;
|
||||
params?: Record<string, any>;
|
||||
currentData?: { id: string; index: number };
|
||||
}
|
||||
) {
|
||||
const { t } = useTranslation();
|
||||
const [dataList, setDataList] = useState<TData['list']>([]);
|
||||
const [hasMorePrev, setHasMorePrev] = useState(true);
|
||||
const [hasMoreNext, setHasMoreNext] = useState(true);
|
||||
|
||||
const anchorRef = useRef({
|
||||
top: null as { _id: string; index: number } | null,
|
||||
bottom: null as { _id: string; index: number } | null
|
||||
});
|
||||
const containerRef = useRef<HTMLDivElement>(null);
|
||||
const itemRefs = useRef<Map<string, HTMLElement | null>>(new Map());
|
||||
|
||||
const scrollToItem = async (id: string, retry = 3) => {
|
||||
const itemIndex = dataList.findIndex((item) => item._id === id);
|
||||
if (itemIndex === -1) return;
|
||||
|
||||
const element = itemRefs.current.get(id);
|
||||
|
||||
if (!element || !containerRef.current) {
|
||||
if (retry > 0) {
|
||||
await delay(500);
|
||||
return scrollToItem(id, retry - 1);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
const elementRect = element.getBoundingClientRect();
|
||||
const containerRect = containerRef.current.getBoundingClientRect();
|
||||
|
||||
const scrollTop = containerRef.current.scrollTop + elementRect.top - containerRect.top;
|
||||
|
||||
containerRef.current.scrollTo({
|
||||
top: scrollTop
|
||||
});
|
||||
};
|
||||
|
||||
const { runAsync: callApi, loading: isLoading } = useRequest2(api);
|
||||
|
||||
let scroolSign = useRef(false);
|
||||
const { runAsync: loadInitData } = useRequest2(
|
||||
async ({ scrollWhenFinish, refresh } = { scrollWhenFinish: true, refresh: false }) => {
|
||||
console.log('loadInitData', params);
|
||||
if (!currentData || isLoading) return;
|
||||
|
||||
const item = dataList.find((item) => item._id === currentData.id);
|
||||
if (item && !refresh) {
|
||||
scrollToItem(item._id);
|
||||
return;
|
||||
}
|
||||
|
||||
const response = await callApi({
|
||||
initialId: currentData.id,
|
||||
initialIndex: currentData.index,
|
||||
pageSize,
|
||||
...params
|
||||
} as TParams);
|
||||
|
||||
setHasMorePrev(response.hasMorePrev);
|
||||
setHasMoreNext(response.hasMoreNext);
|
||||
|
||||
scroolSign.current = scrollWhenFinish;
|
||||
setDataList(response.list);
|
||||
|
||||
if (response.list.length > 0) {
|
||||
anchorRef.current.top = response.list[0];
|
||||
anchorRef.current.bottom = response.list[response.list.length - 1];
|
||||
}
|
||||
},
|
||||
{
|
||||
refreshDeps: [currentData],
|
||||
manual: false
|
||||
}
|
||||
);
|
||||
useEffect(() => {
|
||||
if (scroolSign.current && currentData) {
|
||||
scroolSign.current = false;
|
||||
scrollToItem(currentData.id);
|
||||
}
|
||||
}, [dataList]);
|
||||
|
||||
const { runAsync: loadPrevData, loading: prevLoading } = useRequest2(
|
||||
async (scrollRef = containerRef) => {
|
||||
if (!anchorRef.current.top || !hasMorePrev || isLoading) return;
|
||||
|
||||
const prevScrollTop = scrollRef?.current?.scrollTop || 0;
|
||||
const prevScrollHeight = scrollRef?.current?.scrollHeight || 0;
|
||||
|
||||
const response = await callApi({
|
||||
prevId: anchorRef.current.top._id,
|
||||
prevIndex: anchorRef.current.top.index,
|
||||
pageSize,
|
||||
...params
|
||||
} as TParams);
|
||||
|
||||
if (!response) return;
|
||||
|
||||
setHasMorePrev(response.hasMorePrev);
|
||||
|
||||
if (response.list.length > 0) {
|
||||
setDataList((prev) => [...response.list, ...prev]);
|
||||
anchorRef.current.top = response.list[0];
|
||||
|
||||
setTimeout(() => {
|
||||
if (scrollRef?.current) {
|
||||
const newHeight = scrollRef.current.scrollHeight;
|
||||
const heightDiff = newHeight - prevScrollHeight;
|
||||
scrollRef.current.scrollTop = prevScrollTop + heightDiff;
|
||||
}
|
||||
}, 0);
|
||||
}
|
||||
|
||||
return response;
|
||||
},
|
||||
{
|
||||
refreshDeps: [hasMorePrev, isLoading, params, pageSize]
|
||||
}
|
||||
);
|
||||
|
||||
const { runAsync: loadNextData, loading: nextLoading } = useRequest2(
|
||||
async (scrollRef = containerRef) => {
|
||||
if (!anchorRef.current.bottom || !hasMoreNext || isLoading) return;
|
||||
|
||||
const prevScrollTop = scrollRef?.current?.scrollTop || 0;
|
||||
|
||||
const response = await callApi({
|
||||
nextId: anchorRef.current.bottom._id,
|
||||
nextIndex: anchorRef.current.bottom.index,
|
||||
pageSize,
|
||||
...params
|
||||
} as TParams);
|
||||
|
||||
if (!response) return;
|
||||
|
||||
setHasMoreNext(response.hasMoreNext);
|
||||
|
||||
if (response.list.length > 0) {
|
||||
setDataList((prev) => [...prev, ...response.list]);
|
||||
anchorRef.current.bottom = response.list[response.list.length - 1];
|
||||
|
||||
setTimeout(() => {
|
||||
if (scrollRef?.current) {
|
||||
scrollRef.current.scrollTop = prevScrollTop;
|
||||
}
|
||||
}, 0);
|
||||
}
|
||||
|
||||
return response;
|
||||
},
|
||||
{
|
||||
refreshDeps: [hasMoreNext, isLoading, params, pageSize]
|
||||
}
|
||||
);
|
||||
|
||||
const ScrollData = useMemoizedFn(
|
||||
({
|
||||
children,
|
||||
ScrollContainerRef,
|
||||
...props
|
||||
}: {
|
||||
children: ReactNode;
|
||||
ScrollContainerRef?: React.RefObject<HTMLDivElement>;
|
||||
} & BoxProps) => {
|
||||
const ref = ScrollContainerRef || containerRef;
|
||||
const scroll = useScroll(ref);
|
||||
|
||||
useDebounceEffect(
|
||||
() => {
|
||||
if (!ref?.current || isLoading) return;
|
||||
|
||||
const { scrollTop, scrollHeight, clientHeight } = ref.current;
|
||||
|
||||
// 滚动到底部附近,加载更多下方数据
|
||||
if (scrollTop + clientHeight >= scrollHeight - threshold) {
|
||||
loadNextData(ref);
|
||||
}
|
||||
|
||||
// 滚动到顶部附近,加载更多上方数据
|
||||
if (scrollTop <= threshold) {
|
||||
loadPrevData(ref);
|
||||
}
|
||||
},
|
||||
[scroll],
|
||||
{ wait: 200 }
|
||||
);
|
||||
|
||||
return (
|
||||
<MyBox ref={ref} h={'100%'} overflow={'auto'} isLoading={isLoading} {...props}>
|
||||
{hasMorePrev && prevLoading && (
|
||||
<Box mt={2} fontSize={'xs'} color={'blackAlpha.500'} textAlign={'center'}>
|
||||
{t('common:common.is_requesting')}
|
||||
</Box>
|
||||
)}
|
||||
{children}
|
||||
{hasMoreNext && nextLoading && (
|
||||
<Box mt={2} fontSize={'xs'} color={'blackAlpha.500'} textAlign={'center'}>
|
||||
{t('common:common.is_requesting')}
|
||||
</Box>
|
||||
)}
|
||||
</MyBox>
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
return {
|
||||
dataList,
|
||||
setDataList,
|
||||
isLoading,
|
||||
loadInitData,
|
||||
ScrollData,
|
||||
itemRefs,
|
||||
scrollToItem
|
||||
};
|
||||
}
|
||||
@@ -200,7 +200,7 @@ export function usePagination<DataT, ResT = {}>(
|
||||
// Watch scroll position
|
||||
useThrottleEffect(
|
||||
() => {
|
||||
if (!ref?.current || type !== 'scroll' || noMore) return;
|
||||
if (!ref?.current || type !== 'scroll' || noMore || isLoading) return;
|
||||
const { scrollTop, scrollHeight, clientHeight } = ref.current;
|
||||
|
||||
if (
|
||||
@@ -211,7 +211,7 @@ export function usePagination<DataT, ResT = {}>(
|
||||
fetchData(pageNum + 1, ref);
|
||||
}
|
||||
},
|
||||
[scroll],
|
||||
[scroll, isLoading],
|
||||
{ wait: 50 }
|
||||
);
|
||||
|
||||
|
||||
@@ -21,7 +21,6 @@
|
||||
"edit_channel": "Channel configuration",
|
||||
"enable_channel": "Enable",
|
||||
"forbid_channel": "Disabled",
|
||||
"maxToken_tip": "The model max_tokens parameter, if left blank, means that the model does not support it.",
|
||||
"key_type": "API key format:",
|
||||
"log": "Call log",
|
||||
"log_detail": "Log details",
|
||||
@@ -29,6 +28,7 @@
|
||||
"log_status": "Status",
|
||||
"mapping": "Model Mapping",
|
||||
"mapping_tip": "A valid Json is required. \nThe model can be mapped when sending a request to the actual address. \nFor example:\n{\n \n \"gpt-4o\": \"gpt-4o-test\"\n\n}\n\nWhen FastGPT requests the gpt-4o model, the gpt-4o-test model is sent to the actual address, instead of gpt-4o.",
|
||||
"maxToken_tip": "The model max_tokens parameter, if left blank, means that the model does not support it.",
|
||||
"max_temperature_tip": "If the model temperature parameter is not filled in, it means that the model does not support the temperature parameter.",
|
||||
"model": "Model",
|
||||
"model_name": "Model name",
|
||||
@@ -43,7 +43,7 @@
|
||||
"select_model_placeholder": "Select the model available under this channel",
|
||||
"select_provider_placeholder": "Search for manufacturers",
|
||||
"selected_model_empty": "Choose at least one model",
|
||||
"start_test": "Start testing {{num}} models",
|
||||
"start_test": "Batch test {{num}} models",
|
||||
"test_failed": "There are {{num}} models that report errors",
|
||||
"vlm_model": "Vlm",
|
||||
"vlm_model_tip": "Used to generate additional indexing of images in a document in the knowledge base",
|
||||
|
||||
@@ -1,18 +1,39 @@
|
||||
{
|
||||
"1person": "1 person",
|
||||
"1year": "1 Year",
|
||||
"30mins": "30 Minutes",
|
||||
"7days": "7 Days",
|
||||
"accept": "accept",
|
||||
"action": "operate",
|
||||
"confirm_delete_group": "Confirm to delete group?",
|
||||
"confirm_delete_member": "Confirm to delete member?",
|
||||
"confirm_delete_org": "Confirm to delete organization?",
|
||||
"confirm_forbidden": "Confirm forbidden",
|
||||
"confirm_leave_team": "Confirmed to leave the team? \nAfter exiting, all your resources in the team are transferred to the team owner.",
|
||||
"copy_link": "Copy link",
|
||||
"create_group": "Create group",
|
||||
"create_invitation_link": "Create Invitation Link",
|
||||
"create_org": "Create organization",
|
||||
"create_sub_org": "Create sub-organization",
|
||||
"delete": "delete",
|
||||
"delete_org": "Delete organization",
|
||||
"edit_info": "Edit information",
|
||||
"edit_org_info": "Edit organization information",
|
||||
"expires": "Expiration",
|
||||
"forbid_hint": "After forbidden, this invitation link will become invalid. This action is irreversible. Are you sure you want to deactivate?",
|
||||
"forbid_success": "Forbid success",
|
||||
"forbidden": "Forbidden",
|
||||
"group": "group",
|
||||
"group_name": "Group name",
|
||||
"handle_invitation": "Handle Invitation",
|
||||
"has_forbidden": "Forbidden",
|
||||
"has_invited": "Invited",
|
||||
"ignore": "Ignore",
|
||||
"invitation_link_auto_clean_hint": "Expired links will be automatically cleaned up after 30 days",
|
||||
"invitation_link_description": "Link description",
|
||||
"invitation_link_list": "Invitation link list",
|
||||
"invite_member": "Invite members",
|
||||
"invited": "Invited",
|
||||
"label_sync": "Tag sync",
|
||||
"leave_team_failed": "Leaving the team exception",
|
||||
"manage_member": "Managing members",
|
||||
@@ -31,9 +52,12 @@
|
||||
"search_member_group_name": "Search member/group name",
|
||||
"total_team_members": "{{amount}} members in total",
|
||||
"transfer_ownership": "transfer owner",
|
||||
"unlimited": "Unlimited",
|
||||
"used_times_limit": "Limit",
|
||||
"user_name": "username",
|
||||
"user_team_invite_member": "Invite members",
|
||||
"user_team_leave_team": "Leave the team",
|
||||
"user_team_leave_team_failed": "Failure to leave the team",
|
||||
"waiting": "To be accepted"
|
||||
"waiting": "To be accepted",
|
||||
"invitation_copy_link": "[{{systemName}}] {{userName}} invites you to join the {{teamName}} team, link: {{url}}"
|
||||
}
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
"Delete_all": "Clear All Lexicon",
|
||||
"LLM_model_response_empty": "The model flow response is empty, please check whether the model flow output is normal.",
|
||||
"ai_reasoning": "Thinking process",
|
||||
"chat.quote.No Data": "The file cannot be found",
|
||||
"chat.quote.deleted": "This data has been deleted ~",
|
||||
"chat_history": "Conversation History",
|
||||
"chat_input_guide_lexicon_is_empty": "Lexicon not configured yet",
|
||||
"chat_test_app": "Debug-{{name}}",
|
||||
@@ -16,8 +18,10 @@
|
||||
"contextual_preview": "Contextual Preview {{num}} Items",
|
||||
"csv_input_lexicon_tip": "Only CSV batch import is supported, click to download the template",
|
||||
"custom_input_guide_url": "Custom Lexicon URL",
|
||||
"data_source": "Source Dataset: {{name}}",
|
||||
"dataset_quote_type error": "Knowledge base reference type is wrong, correct type: { datasetId: string }[]",
|
||||
"delete_all_input_guide_confirm": "Are you sure you want to clear the input guide lexicon?",
|
||||
"download_chunks": "Download data",
|
||||
"empty_directory": "This directory is empty~",
|
||||
"file_amount_over": "Exceeded maximum file quantity {{max}}",
|
||||
"file_input": "File input",
|
||||
@@ -40,16 +44,19 @@
|
||||
"query_extension_IO_tokens": "Problem Optimization Input/Output Tokens",
|
||||
"query_extension_result": "Problem optimization results",
|
||||
"question_tip": "From top to bottom, the response order of each module",
|
||||
"read_raw_source": "Open the original text",
|
||||
"reasoning_text": "Thinking process",
|
||||
"response.child total points": "Sub-workflow point consumption",
|
||||
"response.dataset_concat_length": "Combined total",
|
||||
"response.node_inputs": "Node Inputs",
|
||||
"response_hybrid_weight": "Embedding : Full text = {{emb}} : {{text}}",
|
||||
"select": "Select",
|
||||
"select_file": "Upload File",
|
||||
"select_file_img": "Upload file / image",
|
||||
"select_img": "Upload Image",
|
||||
"source_cronJob": "Scheduled execution",
|
||||
"stream_output": "Stream Output",
|
||||
"to_dataset": "Go to the Knowledge Base",
|
||||
"unsupported_file_type": "Unsupported file types",
|
||||
"upload": "Upload",
|
||||
"view_citations": "View References",
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
{
|
||||
"App": "Application",
|
||||
"Download": "Download",
|
||||
"Export": "Export",
|
||||
"FAQ.ai_point_a": "Each time you use the AI model, a certain amount of AI points will be deducted. For detailed calculation standards, please refer to the 'AI Points Calculation Standards' above.\nToken calculation uses the same formula as GPT-3.5, where 1 Token ≈ 0.7 Chinese characters ≈ 0.9 English words. Consecutive characters may be considered as 1 Token.",
|
||||
"FAQ.ai_point_expire_a": "Yes, they will expire. After the current package expires, the AI points will be reset to the new package's AI points. Annual package AI points are valid for one year, not monthly.",
|
||||
@@ -88,6 +89,7 @@
|
||||
"code_error.team_error.group_name_duplicate": "Duplicate group name",
|
||||
"code_error.team_error.group_name_empty": "Group name cannot be empty",
|
||||
"code_error.team_error.group_not_exist": "Group does not exist",
|
||||
"code_error.team_error.invitation_link_invalid": "The invitation link has expired",
|
||||
"code_error.team_error.not_user": "The member cannot be found",
|
||||
"code_error.team_error.org_member_duplicated": "Duplicate organization member",
|
||||
"code_error.team_error.org_member_not_exist": "Organization member does not exist",
|
||||
@@ -96,13 +98,16 @@
|
||||
"code_error.team_error.over_size": "error.team.overSize",
|
||||
"code_error.team_error.plugin_amount_not_enough": "Plugin Limit Reached",
|
||||
"code_error.team_error.re_rank_not_enough": "Search rearrangement cannot be used in the free version~",
|
||||
"code_error.team_error.too_many_invitations": "You have reached the maximum number of active invitation links, please clean up some links first",
|
||||
"code_error.team_error.un_auth": "Unauthorized to Operate This Team",
|
||||
"code_error.team_error.user_not_active": "The user did not accept or has left the team",
|
||||
"code_error.team_error.website_sync_not_enough": "The free version cannot be synchronized with the web site ~",
|
||||
"code_error.team_error.you_have_been_in_the_team": "You are already in this team",
|
||||
"code_error.token_error_code.403": "Invalid Login Status, Please Re-login",
|
||||
"code_error.user_error.balance_not_enough": "Insufficient Account Balance",
|
||||
"code_error.user_error.bin_visitor_guest": "You Are Currently a Guest, Unauthorized to Operate",
|
||||
"code_error.user_error.un_auth_user": "User Not Found",
|
||||
"commercial_function_tip": "Please Upgrade to the Commercial Version to Use This Feature: https://doc.fastgpt.cn/docs/commercial/intro/",
|
||||
"common.Action": "Action",
|
||||
"common.Add": "Add",
|
||||
"common.Add New": "Add New",
|
||||
@@ -252,7 +257,6 @@
|
||||
"common.submit_success": "Submitted Successfully",
|
||||
"common.submitted": "Submitted",
|
||||
"common.support": "Support",
|
||||
"common.system.Commercial version function": "Please Upgrade to the Commercial Version to Use This Feature: https://doc.fastgpt.cn/docs/commercial/intro/",
|
||||
"common.system.Help Chatbot": "Help Chatbot",
|
||||
"common.system.Use Helper": "Use Helper",
|
||||
"common.ui.textarea.Magnifying": "Magnifying",
|
||||
@@ -268,6 +272,7 @@
|
||||
"compliance.compliance.dataset": "Please ensure that your content strictly complies with relevant laws and regulations and avoid containing any illegal or infringing content. \nPlease be careful when uploading materials that may contain sensitive information.",
|
||||
"compliance.dataset": "Please ensure that your content strictly complies with relevant laws and regulations and avoid containing any illegal or infringing content. \nPlease be careful when uploading materials that may contain sensitive information.",
|
||||
"confirm_choice": "Confirm Choice",
|
||||
"contact_way": "Contact information",
|
||||
"contribute_app_template": "Contribute Template",
|
||||
"core.Chat": "Chat",
|
||||
"core.Max Token": "Max Token",
|
||||
@@ -450,6 +455,8 @@
|
||||
"core.chat.module_unexist": "Running failed: Application missing components",
|
||||
"core.chat.quote.Quote Tip": "Only the actual quoted content is displayed here. If the data is updated, it will not be updated in real-time here.",
|
||||
"core.chat.quote.Read Quote": "View Quote",
|
||||
"core.chat.quote.afterUpdate": "After update",
|
||||
"core.chat.quote.beforeUpdate": "Before update",
|
||||
"core.chat.response.Complete Response": "Complete Response",
|
||||
"core.chat.response.Extension model": "Question Optimization Model",
|
||||
"core.chat.response.Read complete response": "View Details",
|
||||
@@ -498,7 +505,6 @@
|
||||
"core.dataset.Empty Dataset": "Empty Dataset",
|
||||
"core.dataset.Empty Dataset Tips": "No Dataset Yet, Create One Now!",
|
||||
"core.dataset.Folder placeholder": "This is a Directory",
|
||||
"core.dataset.Go Dataset": "Go to Dataset",
|
||||
"core.dataset.Intro Placeholder": "This Dataset Has No Introduction Yet",
|
||||
"core.dataset.Manual collection": "Manual Dataset",
|
||||
"core.dataset.My Dataset": "My Dataset",
|
||||
@@ -534,18 +540,13 @@
|
||||
"core.dataset.collection.status.active": "Ready",
|
||||
"core.dataset.collection.sync.result.sameRaw": "Content Unchanged, No Update Needed",
|
||||
"core.dataset.collection.sync.result.success": "Sync Started",
|
||||
"core.dataset.data.Auxiliary Data": "Auxiliary Data",
|
||||
"core.dataset.data.Auxiliary Data Placeholder": "This part is optional and is usually used to construct structured prompts in conjunction with the 'Data Content' above for special scenarios, up to {{maxToken}} characters.",
|
||||
"core.dataset.data.Auxiliary Data Tip": "This part is optional\nThis content is usually used to construct structured prompts in conjunction with the data content above for special scenarios",
|
||||
"core.dataset.data.Data Content": "Related Data Content",
|
||||
"core.dataset.data.Data Content Placeholder": "This input box is required. This content is usually a description of the knowledge point or a user's question, up to {{maxToken}} characters.",
|
||||
"core.dataset.data.Data Content Tip": "This input box is required\nThis content is usually a description of the knowledge point or a user's question.",
|
||||
"core.dataset.data.Default Index Tip": "Cannot be edited. The default index will use the text of 'Related Data Content' and 'Auxiliary Data' to generate the index directly.",
|
||||
"core.dataset.data.Edit": "Edit Data",
|
||||
"core.dataset.data.Empty Tip": "This collection has no data yet",
|
||||
"core.dataset.data.Main Content": "Main Content",
|
||||
"core.dataset.data.Search data placeholder": "Search Related Data",
|
||||
"core.dataset.data.Too Long": "Total Length Exceeded",
|
||||
"core.dataset.data.Updated": "Updated",
|
||||
"core.dataset.data.group": "Group",
|
||||
"core.dataset.data.unit": "Items",
|
||||
"core.dataset.embedding model tip": "The index model can convert natural language into vectors for semantic search.\nNote that different index models cannot be used together. Once an index model is selected, it cannot be changed.",
|
||||
@@ -626,7 +627,7 @@
|
||||
"core.dataset.search.score.reRank desc": "Calculate the relevance between sentences using the re-rank model, ranging from 0 to 1.",
|
||||
"core.dataset.search.score.rrf": "Comprehensive Ranking",
|
||||
"core.dataset.search.score.rrf desc": "Merge multiple search results using the reciprocal rank fusion method.",
|
||||
"core.dataset.search.search mode": "Search Mode",
|
||||
"core.dataset.search.search mode": "Search Method",
|
||||
"core.dataset.status.active": "Ready",
|
||||
"core.dataset.status.syncing": "Syncing",
|
||||
"core.dataset.test.Batch test": "Batch Test",
|
||||
@@ -832,6 +833,11 @@
|
||||
"core.workflow.variable": "Variable",
|
||||
"create": "Create",
|
||||
"cron_job_run_app": "Scheduled Task",
|
||||
"data_index_custom": "Custom index",
|
||||
"data_index_default": "Default index",
|
||||
"data_index_image": "Image Index",
|
||||
"data_index_question": "Inferred question index",
|
||||
"data_index_summary": "Summary Index",
|
||||
"dataset.Confirm move the folder": "Confirm to Move to This Directory",
|
||||
"dataset.Confirm to delete the data": "Confirm to Delete This Data?",
|
||||
"dataset.Confirm to delete the file": "Confirm to Delete This File and All Its Data?",
|
||||
@@ -867,6 +873,12 @@
|
||||
"dataset.dataset_name": "Dataset Name",
|
||||
"dataset.deleteFolderTips": "Confirm to Delete This Folder and All Its Contained Datasets? Data Cannot Be Recovered After Deletion, Please Confirm!",
|
||||
"dataset.test.noResult": "No Search Results",
|
||||
"dataset_data_import_q_placeholder": "Up to {{maxToken}} words.",
|
||||
"dataset_data_input_a": "Answer",
|
||||
"dataset_data_input_chunk": "Chunk",
|
||||
"dataset_data_input_chunk_content": "Chunk",
|
||||
"dataset_data_input_q": "question",
|
||||
"dataset_data_input_qa": "QA",
|
||||
"dataset_text_model_tip": "Used for text processing in the knowledge base preprocessing stage, such as automatic supplementary indexing, Q&A pair extraction.",
|
||||
"deep_rag_search": "In-depth search",
|
||||
"delete_api": "Are you sure you want to delete this API key? \nAfter deletion, the key will become invalid immediately and the corresponding conversation log will not be deleted. Please confirm!",
|
||||
@@ -1013,6 +1025,7 @@
|
||||
"question_feedback": "Work order",
|
||||
"read_quote": "View citations",
|
||||
"required": "Required",
|
||||
"rerank_weight": "Rearrange weights",
|
||||
"resume_failed": "Resume Failed",
|
||||
"select_reference_variable": "Select Reference Variable",
|
||||
"share_link": "Share Link",
|
||||
@@ -1027,6 +1040,8 @@
|
||||
"support.outlink.Max usage points": "Points Limit",
|
||||
"support.outlink.Max usage points tip": "The maximum number of points allowed for this link. It cannot be used after exceeding the limit. -1 means unlimited.",
|
||||
"support.outlink.Usage points": "Points Consumption",
|
||||
"support.outlink.share.Chat_quote_reader": "Full text reader",
|
||||
"support.outlink.share.Full_text tips": "Allows reading of the complete dataset from which the referenced fragment is derived",
|
||||
"support.outlink.share.Response Quote": "Return Quote",
|
||||
"support.outlink.share.Response Quote tips": "Return quoted content in the share link, but do not allow users to download the original document",
|
||||
"support.outlink.share.running_node": "Running node",
|
||||
@@ -1242,11 +1257,6 @@
|
||||
"user.team.Check Team": "Switch",
|
||||
"user.team.Confirm Invite": "Confirm Invite",
|
||||
"user.team.Create Team": "Create New Team",
|
||||
"user.team.Invite Member": "Invite Member",
|
||||
"user.team.Invite Member Failed Tip": "Failed to Invite Member",
|
||||
"user.team.Invite Member Result Tip": "Invite Result Tip",
|
||||
"user.team.Invite Member Success Tip": "Member Invitation Completed\nSuccess: {{success}} people\nInvalid Username: {{inValid}}\nAlready in Team: {{inTeam}}",
|
||||
"user.team.Invite Member Tips": "The other party can view or use other resources within the team",
|
||||
"user.team.Leave Team": "Leave Team",
|
||||
"user.team.Leave Team Failed": "Failed to Leave Team",
|
||||
"user.team.Member": "Member",
|
||||
@@ -1264,13 +1274,9 @@
|
||||
"user.team.Team Tags Async": "Tag Sync",
|
||||
"user.team.Team Tags Async Success": "Link Error Successful, Tag Information Updated",
|
||||
"user.team.Update Team": "Update Team Information",
|
||||
"user.team.invite.Accept Confirm": "Confirm to join this team?",
|
||||
"user.team.invite.Accepted": "Joined Team",
|
||||
"user.team.invite.Deal Width Footer Tip": "It will automatically close after processing",
|
||||
"user.team.invite.Reject": "Invitation Rejected",
|
||||
"user.team.invite.Reject Confirm": "Confirm to reject this invitation?",
|
||||
"user.team.invite.accept": "Accept",
|
||||
"user.team.invite.reject": "Reject",
|
||||
"user.team.member.Confirm Leave": "Confirm to leave this team?",
|
||||
"user.team.member.active": "Joined",
|
||||
"user.team.member.reject": "Rejected",
|
||||
|
||||
@@ -27,12 +27,7 @@
|
||||
"custom_data_process_params_desc": "Customize data processing rules",
|
||||
"data.ideal_chunk_length": "ideal block length",
|
||||
"data_amount": "{{dataAmount}} Datas, {{indexAmount}} Indexes",
|
||||
"data_index_custom": "Custom index",
|
||||
"data_index_default": "Default index",
|
||||
"data_index_image": "Image Index",
|
||||
"data_index_num": "Index {{index}}",
|
||||
"data_index_question": "Inferred question index",
|
||||
"data_index_summary": "Summary index",
|
||||
"data_process_params": "Params",
|
||||
"data_process_setting": "Processing config",
|
||||
"dataset.Unsupported operation": "dataset.Unsupported operation",
|
||||
@@ -69,6 +64,7 @@
|
||||
"import_model_config": "Model selection",
|
||||
"import_param_setting": "Parameter settings",
|
||||
"import_select_file": "Select a file",
|
||||
"import_select_link": "Enter link",
|
||||
"is_open_schedule": "Enable scheduled synchronization",
|
||||
"keep_image": "Keep the picture",
|
||||
"move.hint": "After moving, the selected knowledge base/folder will inherit the permission settings of the new folder, and the original permission settings will become invalid.",
|
||||
|
||||