@@ -56,7 +56,7 @@ FastGPT 采用了`PostgresSQL`的`PG Vector`插件作为向量检索器,索引
|
||||
|
||||
### 检索方案
|
||||
|
||||
1. 通过`问题优化`实现指代消除和问题扩展,从而增加连续对话的检索能力以及语义丰富度。
|
||||
1. 通过`问题补全`实现指代消除和问题扩展,从而增加连续对话的检索能力以及语义丰富度。
|
||||
2. 通过`Concat query`来增加`Rerank`连续对话的时,排序的准确性。
|
||||
3. 通过`RRF`合并方式,综合多个渠道的检索效果。
|
||||
4. 通过`Rerank`来二次排序,提高精度。
|
||||
@@ -97,7 +97,7 @@ FastGPT 采用了`PostgresSQL`的`PG Vector`插件作为向量检索器,索引
|
||||
|
||||
#### 结果重排
|
||||
|
||||
利用`ReRank`模型对搜索结果进行重排,绝大多数情况下,可以有效提高搜索结果的准确率。不过,重排模型与问题的完整度(主谓语齐全)有一些关系,通常会先走问题优化后再进行搜索-重排。重排后可以得到一个`0-1`的得分,代表着搜索内容与问题的相关度,该分数通常比向量的得分更加精确,可以根据得分进行过滤。
|
||||
利用`ReRank`模型对搜索结果进行重排,绝大多数情况下,可以有效提高搜索结果的准确率。不过,重排模型与问题的完整度(主谓语齐全)有一些关系,通常会先走问题补全后再进行搜索-重排。重排后可以得到一个`0-1`的得分,代表着搜索内容与问题的相关度,该分数通常比向量的得分更加精确,可以根据得分进行过滤。
|
||||
|
||||
FastGPT 会使用 `RRF` 对重排结果、向量搜索结果、全文检索结果进行合并,得到最终的搜索结果。
|
||||
|
||||
@@ -115,7 +115,7 @@ FastGPT 会使用 `RRF` 对重排结果、向量搜索结果、全文检索结
|
||||
|
||||
该值仅在`语义检索`或使用`结果重排`时生效。
|
||||
|
||||
### 问题优化
|
||||
### 问题补全
|
||||
|
||||
#### 背景
|
||||
|
||||
@@ -125,7 +125,7 @@ FastGPT 会使用 `RRF` 对重排结果、向量搜索结果、全文检索结
|
||||
|
||||

|
||||
|
||||
用户在提问“第二点是什么”的时候,只会去知识库里查找“第二点是什么”,压根查不到内容。实际上需要查询的是“QA结构是什么”。因此我们需要引入一个【问题优化】模块,来对用户当前的问题进行补全,从而使得知识库搜索能够搜索到合适的内容。使用补全后效果如下:
|
||||
用户在提问“第二点是什么”的时候,只会去知识库里查找“第二点是什么”,压根查不到内容。实际上需要查询的是“QA结构是什么”。因此我们需要引入一个【问题补全】模块,来对用户当前的问题进行补全,从而使得知识库搜索能够搜索到合适的内容。使用补全后效果如下:
|
||||
|
||||

|
||||
|
||||
|
@@ -13,7 +13,163 @@ weight: 708
|
||||
|
||||
这个配置文件中包含了系统级参数、AI 对话的模型、function 模型等……
|
||||
|
||||
## 4.6.8+ 版本新配置文件
|
||||
## 4.6.8 以前版本完整配置参数
|
||||
|
||||
**使用时,请务必去除注释!**
|
||||
|
||||
以下配置适用于V4.6.6-alpha版本以后
|
||||
|
||||
```json
|
||||
{
|
||||
"systemEnv": {
|
||||
"vectorMaxProcess": 15, // 向量生成最大进程,结合数据库性能和 key 来设置
|
||||
"qaMaxProcess": 15, // QA 生成最大进程,结合数据库性能和 key 来设置
|
||||
"pgHNSWEfSearch": 100 // pg vector 索引参数,越大精度高但速度慢
|
||||
},
|
||||
"chatModels": [ // 对话模型
|
||||
{
|
||||
"model": "gpt-3.5-turbo-1106",
|
||||
"name": "GPT35-1106",
|
||||
"inputPrice": 0, // 输入价格。 xx元/1k tokens
|
||||
"outputPrice": 0, // 输出价格。 xx元/1k tokens
|
||||
"maxContext": 16000, // 最大上下文长度
|
||||
"maxResponse": 4000, // 最大回复长度
|
||||
"quoteMaxToken": 2000, // 最大引用内容长度
|
||||
"maxTemperature": 1.2, // 最大温度值
|
||||
"censor": false, // 是否开启敏感词过滤(商业版)
|
||||
"vision": false, // 支持图片输入
|
||||
"defaultSystemChatPrompt": ""
|
||||
},
|
||||
{
|
||||
"model": "gpt-3.5-turbo-16k",
|
||||
"name": "GPT35-16k",
|
||||
"maxContext": 16000,
|
||||
"maxResponse": 16000,
|
||||
"inputPrice": 0,
|
||||
"outputPrice": 0,
|
||||
"quoteMaxToken": 8000,
|
||||
"maxTemperature": 1.2,
|
||||
"censor": false,
|
||||
"vision": false,
|
||||
"defaultSystemChatPrompt": ""
|
||||
},
|
||||
{
|
||||
"model": "gpt-4",
|
||||
"name": "GPT4-8k",
|
||||
"maxContext": 8000,
|
||||
"maxResponse": 8000,
|
||||
"inputPrice": 0,
|
||||
"outputPrice": 0,
|
||||
"quoteMaxToken": 4000,
|
||||
"maxTemperature": 1.2,
|
||||
"censor": false,
|
||||
"vision": false,
|
||||
"defaultSystemChatPrompt": ""
|
||||
},
|
||||
{
|
||||
"model": "gpt-4-vision-preview",
|
||||
"name": "GPT4-Vision",
|
||||
"maxContext": 128000,
|
||||
"maxResponse": 4000,
|
||||
"inputPrice": 0,
|
||||
"outputPrice": 0,
|
||||
"quoteMaxToken": 100000,
|
||||
"maxTemperature": 1.2,
|
||||
"censor": false,
|
||||
"vision": true,
|
||||
"defaultSystemChatPrompt": ""
|
||||
}
|
||||
],
|
||||
"qaModels": [ // QA 生成模型
|
||||
{
|
||||
"model": "gpt-3.5-turbo-16k",
|
||||
"name": "GPT35-16k",
|
||||
"maxContext": 16000,
|
||||
"maxResponse": 16000,
|
||||
"inputPrice": 0,
|
||||
"outputPrice": 0
|
||||
}
|
||||
],
|
||||
"cqModels": [ // 问题分类模型
|
||||
{
|
||||
"model": "gpt-3.5-turbo-1106",
|
||||
"name": "GPT35-1106",
|
||||
"maxContext": 16000,
|
||||
"maxResponse": 4000,
|
||||
"inputPrice": 0,
|
||||
"outputPrice": 0,
|
||||
"toolChoice": true, // 是否支持openai的 toolChoice, 不支持的模型需要设置为 false,会走提示词生成
|
||||
"functionPrompt": ""
|
||||
},
|
||||
{
|
||||
"model": "gpt-4",
|
||||
"name": "GPT4-8k",
|
||||
"maxContext": 8000,
|
||||
"maxResponse": 8000,
|
||||
"inputPrice": 0,
|
||||
"outputPrice": 0,
|
||||
"toolChoice": true,
|
||||
"functionPrompt": ""
|
||||
}
|
||||
],
|
||||
"extractModels": [ // 内容提取模型
|
||||
{
|
||||
"model": "gpt-3.5-turbo-1106",
|
||||
"name": "GPT35-1106",
|
||||
"maxContext": 16000,
|
||||
"maxResponse": 4000,
|
||||
"inputPrice": 0,
|
||||
"outputPrice": 0,
|
||||
"toolChoice": true,
|
||||
"functionPrompt": ""
|
||||
}
|
||||
],
|
||||
"qgModels": [ // 生成下一步指引
|
||||
{
|
||||
"model": "gpt-3.5-turbo-1106",
|
||||
"name": "GPT35-1106",
|
||||
"maxContext": 1600,
|
||||
"maxResponse": 4000,
|
||||
"inputPrice": 0,
|
||||
"outputPrice": 0
|
||||
}
|
||||
],
|
||||
"vectorModels": [ // 向量模型
|
||||
{
|
||||
"model": "text-embedding-ada-002",
|
||||
"name": "Embedding-2",
|
||||
"inputPrice": 0,
|
||||
"defaultToken": 700,
|
||||
"maxToken": 3000
|
||||
}
|
||||
],
|
||||
"reRankModels": [], // 重排模型,暂时填空数组
|
||||
"audioSpeechModels": [
|
||||
{
|
||||
"model": "tts-1",
|
||||
"name": "OpenAI TTS1",
|
||||
"inputPrice": 0,
|
||||
"baseUrl": "",
|
||||
"key": "",
|
||||
"voices": [
|
||||
{ "label": "Alloy", "value": "alloy", "bufferId": "openai-Alloy" },
|
||||
{ "label": "Echo", "value": "echo", "bufferId": "openai-Echo" },
|
||||
{ "label": "Fable", "value": "fable", "bufferId": "openai-Fable" },
|
||||
{ "label": "Onyx", "value": "onyx", "bufferId": "openai-Onyx" },
|
||||
{ "label": "Nova", "value": "nova", "bufferId": "openai-Nova" },
|
||||
{ "label": "Shimmer", "value": "shimmer", "bufferId": "openai-Shimmer" }
|
||||
]
|
||||
}
|
||||
],
|
||||
"whisperModel": {
|
||||
"model": "whisper-1",
|
||||
"name": "Whisper1",
|
||||
"inputPrice": 0
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 4.6.8 新配置文件
|
||||
|
||||
llm模型全部合并
|
||||
|
||||
@@ -33,10 +189,11 @@ llm模型全部合并
|
||||
"maxResponse": 4000, // 最大回复
|
||||
"quoteMaxToken": 13000, // 最大引用内容
|
||||
"maxTemperature": 1.2, // 最大温度
|
||||
"charsPointsPrice": 0,
|
||||
"inputPrice": 0,
|
||||
"outputPrice": 0,
|
||||
"censor": false,
|
||||
"vision": false, // 是否支持图片输入
|
||||
"datasetProcess": false, // 是否设置为知识库处理模型(QA),务必保证至少有一个为true,否则知识库会报错
|
||||
"datasetProcess": false, // 是否设置为知识库处理模型
|
||||
"toolChoice": true, // 是否支持工具选择
|
||||
"functionCall": false, // 是否支持函数调用
|
||||
"customCQPrompt": "", // 自定义文本分类提示词(不支持工具和函数调用的模型
|
||||
@@ -51,7 +208,8 @@ llm模型全部合并
|
||||
"maxResponse": 16000,
|
||||
"quoteMaxToken": 13000,
|
||||
"maxTemperature": 1.2,
|
||||
"charsPointsPrice": 0,
|
||||
"inputPrice": 0,
|
||||
"outputPrice": 0,
|
||||
"censor": false,
|
||||
"vision": false,
|
||||
"datasetProcess": true,
|
||||
@@ -69,7 +227,8 @@ llm模型全部合并
|
||||
"maxResponse": 4000,
|
||||
"quoteMaxToken": 100000,
|
||||
"maxTemperature": 1.2,
|
||||
"charsPointsPrice": 0,
|
||||
"inputPrice": 0,
|
||||
"outputPrice": 0,
|
||||
"censor": false,
|
||||
"vision": false,
|
||||
"datasetProcess": false,
|
||||
@@ -87,9 +246,10 @@ llm模型全部合并
|
||||
"maxResponse": 4000,
|
||||
"quoteMaxToken": 100000,
|
||||
"maxTemperature": 1.2,
|
||||
"charsPointsPrice": 0,
|
||||
"inputPrice": 0,
|
||||
"outputPrice": 0,
|
||||
"censor": false,
|
||||
"vision": true,
|
||||
"vision": false,
|
||||
"datasetProcess": false,
|
||||
"toolChoice": true,
|
||||
"functionCall": false,
|
||||
@@ -103,7 +263,8 @@ llm模型全部合并
|
||||
{
|
||||
"model": "text-embedding-ada-002",
|
||||
"name": "Embedding-2",
|
||||
"charsPointsPrice": 0,
|
||||
"inputPrice": 0,
|
||||
"outputPrice": 0,
|
||||
"defaultToken": 700,
|
||||
"maxToken": 3000,
|
||||
"weight": 100,
|
||||
@@ -115,7 +276,8 @@ llm模型全部合并
|
||||
{
|
||||
"model": "tts-1",
|
||||
"name": "OpenAI TTS1",
|
||||
"charsPointsPrice": 0,
|
||||
"inputPrice": 0,
|
||||
"outputPrice": 0,
|
||||
"voices": [
|
||||
{ "label": "Alloy", "value": "alloy", "bufferId": "openai-Alloy" },
|
||||
{ "label": "Echo", "value": "echo", "bufferId": "openai-Echo" },
|
||||
@@ -129,7 +291,8 @@ llm模型全部合并
|
||||
"whisperModel": {
|
||||
"model": "whisper-1",
|
||||
"name": "Whisper1",
|
||||
"charsPointsPrice": 0
|
||||
"inputPrice": 0,
|
||||
"outputPrice": 0
|
||||
}
|
||||
}
|
||||
```
|
||||
@@ -150,7 +313,7 @@ llm模型全部合并
|
||||
{
|
||||
"model": "bge-reranker-base", // 随意
|
||||
"name": "检索重排-base", // 随意
|
||||
"charsPointsPrice": 0,
|
||||
"inputPrice": 0,
|
||||
"requestUrl": "{{host}}/api/v1/rerank",
|
||||
"requestAuth": "安全凭证,已自动补 Bearer"
|
||||
}
|
||||
|
@@ -110,7 +110,6 @@ curl -O https://raw.githubusercontent.com/labring/FastGPT/main/projects/app/data
|
||||
cd 项目目录
|
||||
# 创建 mongo 密钥
|
||||
openssl rand -base64 756 > ./mongodb.key
|
||||
# 600不行可以用chmod 999
|
||||
chmod 600 ./mongodb.key
|
||||
chown 999:root ./mongodb.key
|
||||
# 启动容器
|
||||
|
@@ -116,7 +116,8 @@ CHAT_API_KEY=sk-xxxxxx
|
||||
"maxResponse": 4000, // 最大回复
|
||||
"quoteMaxToken": 13000, // 最大引用内容
|
||||
"maxTemperature": 1.2, // 最大温度
|
||||
"charsPointsPrice": 0,
|
||||
"inputPrice": 0,
|
||||
"outputPrice": 0,
|
||||
"censor": false,
|
||||
"vision": false, // 是否支持图片输入
|
||||
"datasetProcess": false, // 是否设置为知识库处理模型
|
||||
|
@@ -13,25 +13,12 @@ weight: 853
|
||||
|
||||
|
||||
|
||||
## 创建训练订单(4.6.9地址发生改动)
|
||||
## 创建训练订单
|
||||
|
||||
{{< tabs tabTotal="2" >}}
|
||||
{{< tab tabName="请求示例" >}}
|
||||
{{< markdownify >}}
|
||||
|
||||
**新例子**
|
||||
|
||||
```bash
|
||||
curl --location --request POST 'https://api.fastgpt.in/api/support/wallet/usage/createTrainingUsage' \
|
||||
--header 'Authorization: Bearer {{apikey}}' \
|
||||
--header 'Content-Type: application/json' \
|
||||
--data-raw '{
|
||||
"name": "可选,自定义订单名称,例如:文档训练-fastgpt.docx"
|
||||
}'
|
||||
```
|
||||
|
||||
**x例子**
|
||||
|
||||
```bash
|
||||
curl --location --request POST 'https://api.fastgpt.in/api/support/wallet/bill/createTrainingBill' \
|
||||
--header 'Authorization: Bearer {{apikey}}' \
|
||||
@@ -167,7 +154,7 @@ curl --location --request GET 'http://localhost:3000/api/core/dataset/list?paren
|
||||
"vectorModel": {
|
||||
"model": "text-embedding-ada-002",
|
||||
"name": "Embedding-2",
|
||||
"charsPointsPrice": 0,
|
||||
"inputPrice": 0,
|
||||
"defaultToken": 512,
|
||||
"maxToken": 8000,
|
||||
"weight": 100
|
||||
@@ -226,7 +213,7 @@ curl --location --request GET 'http://localhost:3000/api/core/dataset/detail?id=
|
||||
"vectorModel": {
|
||||
"model": "text-embedding-ada-002",
|
||||
"name": "Embedding-2",
|
||||
"charsPointsPrice": 0,
|
||||
"inputPrice": 0,
|
||||
"defaultToken": 512,
|
||||
"maxToken": 8000,
|
||||
"weight": 100
|
||||
@@ -236,7 +223,8 @@ curl --location --request GET 'http://localhost:3000/api/core/dataset/detail?id=
|
||||
"name": "FastAI-16k",
|
||||
"maxContext": 16000,
|
||||
"maxResponse": 16000,
|
||||
"charsPointsPrice": 0
|
||||
"inputPrice": 0,
|
||||
"outputPrice": 0
|
||||
},
|
||||
"intro": "",
|
||||
"permission": "private",
|
||||
@@ -812,33 +800,6 @@ curl --location --request DELETE 'http://localhost:3000/api/core/dataset/collect
|
||||
|
||||
## 数据
|
||||
|
||||
### 数据的结构
|
||||
|
||||
**Data结构**
|
||||
|
||||
| 字段 | 类型 | 说明 | 必填 |
|
||||
| --- | --- | --- | --- |
|
||||
| teamId | String | 团队ID | ✅ |
|
||||
| tmbId | String | 成员ID | ✅ |
|
||||
| datasetId | String | 知识库ID | ✅ |
|
||||
| collectionId | String | 集合ID | ✅ |
|
||||
| q | String | 主要数据 | ✅ |
|
||||
| a | String | 辅助数据 | ✖ |
|
||||
| fullTextToken | String | 分词 | ✖ |
|
||||
| indexes | Index[] | 向量索引 | ✅ |
|
||||
| updateTime | Date | 更新时间 | ✅ |
|
||||
| chunkIndex | Number | 分块下表 | ✖ |
|
||||
|
||||
**Index结构**
|
||||
|
||||
每组数据的自定义索引最多5个
|
||||
|
||||
| 字段 | 类型 | 说明 | 必填 |
|
||||
| --- | --- | --- | --- |
|
||||
| defaultIndex | Boolean | 是否为默认索引 | ✅ |
|
||||
| dataId | String | 关联的向量ID | ✅ |
|
||||
| text | String | 文本内容 | ✅ |
|
||||
|
||||
### 为集合批量添加添加数据
|
||||
|
||||
注意,每次最多推送 200 组数据。
|
||||
@@ -864,14 +825,11 @@ curl --location --request POST 'https://api.fastgpt.in/api/core/dataset/data/pus
|
||||
{
|
||||
"q": "你会什么?",
|
||||
"a": "我什么都会",
|
||||
"indexes": [
|
||||
{
|
||||
"text":"自定义索引1"
|
||||
},
|
||||
{
|
||||
"text":"自定义索引2"
|
||||
}
|
||||
]
|
||||
"indexes": [{
|
||||
"defaultIndex": false,
|
||||
"type":"custom",
|
||||
"text":"自定义索引,不使用默认索引"
|
||||
}]
|
||||
}
|
||||
]
|
||||
}'
|
||||
@@ -892,7 +850,7 @@ curl --location --request POST 'https://api.fastgpt.in/api/core/dataset/data/pus
|
||||
- data:(具体数据)
|
||||
- q: 主要数据(必填)
|
||||
- a: 辅助数据(选填)
|
||||
- indexes: 自定义索引(选填)。可以不传或者传空数组,默认都会使用q和a组成一个索引。
|
||||
- indexes: 自定义索引(选填),不传入则默认使用q和a构建索引。也可以传入
|
||||
{{% /alert %}}
|
||||
|
||||
{{< /markdownify >}}
|
||||
@@ -908,6 +866,7 @@ curl --location --request POST 'https://api.fastgpt.in/api/core/dataset/data/pus
|
||||
"data": {
|
||||
"insertLen": 1, // 最终插入成功的数量
|
||||
"overToken": [], // 超出 token 的
|
||||
|
||||
"repeat": [], // 重复的数量
|
||||
"error": [] // 其他错误
|
||||
}
|
||||
@@ -1091,16 +1050,7 @@ curl --location --request PUT 'http://localhost:3000/api/core/dataset/data/updat
|
||||
"id":"65abd4b29d1448617cba61db",
|
||||
"q":"测试111",
|
||||
"a":"sss",
|
||||
"indexes":[
|
||||
{
|
||||
"dataId": "xxx",
|
||||
"defaultIndex":false,
|
||||
"text":"自定义索引1"
|
||||
},
|
||||
{
|
||||
"text":"修改后的自定义索引2。(会删除原来的自定义索引2,并插入新的自定义索引2)"
|
||||
}
|
||||
]
|
||||
"indexes":[]
|
||||
}'
|
||||
```
|
||||
|
||||
@@ -1114,7 +1064,7 @@ curl --location --request PUT 'http://localhost:3000/api/core/dataset/data/updat
|
||||
- id: 数据的id
|
||||
- q: 主要数据(选填)
|
||||
- a: 辅助数据(选填)
|
||||
- indexes: 自定义索引(选填),类型参考`为集合批量添加添加数据`。如果创建时候有自定义索引,
|
||||
- indexes: 自定义索引(选填),类型参考`为集合批量添加添加数据`,建议直接不传。更新q,a后,如果有默认索引,则会直接更新默认索引。
|
||||
{{% /alert %}}
|
||||
|
||||
{{< /markdownify >}}
|
||||
|
@@ -169,6 +169,8 @@ curl --location --request POST '{{host}}/shareAuth/start' \
|
||||
|
||||
响应值与[chat 接口格式相同](/docs/development/openapi/chat/#响应),仅多了一个`token`。
|
||||
|
||||
可以重点关注`responseData`里的`price`值,`price`与实际价格的倍率为`100000`,即 100000=1元。
|
||||
|
||||
```bash
|
||||
curl --location --request POST '{{host}}/shareAuth/finish' \
|
||||
--header 'Content-Type: application/json' \
|
||||
@@ -176,117 +178,72 @@ curl --location --request POST '{{host}}/shareAuth/finish' \
|
||||
"token": "{{authToken}}",
|
||||
"responseData": [
|
||||
{
|
||||
"moduleName": "core.module.template.Dataset search",
|
||||
"moduleType": "datasetSearchNode",
|
||||
"totalPoints": 1.5278,
|
||||
"query": "导演是谁\n《铃芽之旅》的导演是谁?\n这部电影的导演是谁?\n谁是《铃芽之旅》的导演?",
|
||||
"model": "Embedding-2(旧版,不推荐使用)",
|
||||
"charsLength": 1524,
|
||||
"similarity": 0.83,
|
||||
"limit": 400,
|
||||
"searchMode": "embedding",
|
||||
"searchUsingReRank": false,
|
||||
"extensionModel": "FastAI-4k",
|
||||
"extensionResult": "《铃芽之旅》的导演是谁?\n这部电影的导演是谁?\n谁是《铃芽之旅》的导演?",
|
||||
"runningTime": 2.15
|
||||
"moduleName": "KB Search",
|
||||
"price": 1.2000000000000002,
|
||||
"model": "Embedding-2",
|
||||
"tokens": 6,
|
||||
"similarity": 0.61,
|
||||
"limit": 3
|
||||
},
|
||||
{
|
||||
"moduleName": "AI 对话",
|
||||
"moduleType": "chatNode",
|
||||
"totalPoints": 0.593,
|
||||
"moduleName": "AI Chat",
|
||||
"price": 454.5,
|
||||
"model": "FastAI-4k",
|
||||
"charsLength": 593,
|
||||
"query": "导演是谁",
|
||||
"maxToken": 2000,
|
||||
"tokens": 303,
|
||||
"question": "导演是谁",
|
||||
"answer": "电影《铃芽之旅》的导演是新海诚。",
|
||||
"maxToken": 2050,
|
||||
"quoteList": [
|
||||
{
|
||||
"id": "65bb346a53698398479a8854",
|
||||
"q": "导演是谁?",
|
||||
"dataset_id": "646627f4f7b896cfd8910e38",
|
||||
"id": "8099",
|
||||
"q": "本作的主人公是谁?",
|
||||
"a": "本作的主人公是名叫铃芽的少女。",
|
||||
"source": "手动修改"
|
||||
},
|
||||
{
|
||||
"dataset_id": "646627f4f7b896cfd8910e38",
|
||||
"id": "8686",
|
||||
"q": "电影《铃芽之旅》男主角是谁?",
|
||||
"a": "电影《铃芽之旅》男主角是宗像草太,由松村北斗配音。",
|
||||
"source": ""
|
||||
},
|
||||
{
|
||||
"dataset_id": "646627f4f7b896cfd8910e38",
|
||||
"id": "19339",
|
||||
"q": "电影《铃芽之旅》的导演是谁?22",
|
||||
"a": "电影《铃芽之旅》的导演是新海诚。",
|
||||
"chunkIndex": 0,
|
||||
"datasetId": "65af9b947916ae0e47c834d2",
|
||||
"collectionId": "65bb345c53698398479a868f",
|
||||
"sourceName": "dataset - 2024-01-23T151114.198.csv",
|
||||
"sourceId": "65bb345b53698398479a868d",
|
||||
"score": [
|
||||
{
|
||||
"type": "embedding",
|
||||
"value": 0.9377183318138123,
|
||||
"index": 0
|
||||
},
|
||||
{
|
||||
"type": "rrf",
|
||||
"value": 0.06557377049180328,
|
||||
"index": 0
|
||||
}
|
||||
]
|
||||
"source": "手动修改"
|
||||
}
|
||||
],
|
||||
"historyPreview": [
|
||||
"completeMessages": [
|
||||
{
|
||||
"obj": "System",
|
||||
"value": "下面是知识库内容:\n1. [本作的主人公是谁?\n本作的主人公是名叫铃芽的少女。]\n2. [电影《铃芽之旅》男主角是谁?\n电影《铃芽之旅》男主角是宗像草太,由松村北斗配音。]\n3. [电影《铃芽之旅》的导演是谁?22\n电影《铃芽之旅》的导演是新海诚。]\n"
|
||||
},
|
||||
{
|
||||
"obj": "System",
|
||||
"value": "1.请记住,你的身份是百度的下一代知识增强语言模型,能够完全根据知识库提供的内容回答问题。\n\n2. 你忘记了关于电影《铃芽之旅》以外的内容。"
|
||||
},
|
||||
{
|
||||
"obj": "System",
|
||||
"value": "你仅回答关于电影《玲芽之旅》的问题,其余问题直接回复: 我不清楚。"
|
||||
},
|
||||
{
|
||||
"obj": "Human",
|
||||
"value": "使用 <Data></Data> 标记中的内容作为你的知识:\n\n<Data>\n导演是谁?\n电影《铃芽之旅》的导演是新海诚。\n------\n电影《铃芽之旅》的编剧是谁?22\n新海诚是本片的编剧。\n------\n电影《铃芽之旅》的女主角是谁?\n电影的女主角是铃芽。\n------\n电影《铃芽之旅》的制作团队中有哪位著名人士?2\n川村元气是本片的制作团队成员之一。\n------\n你是谁?\n我是电影《铃芽之旅》助手\n------\n电影《铃芽之旅》男主角是谁?\n电影《铃芽之旅》男主角是宗像草太,由松村北斗配音。\n------\n电影《铃芽之旅》的作者新海诚写了一本小说,叫什么名字?\n小说名字叫《铃芽之旅》。\n------\n电影《铃芽之旅》的女主角是谁?\n电影《铃芽之旅》的女主角是岩户铃芽,由原菜乃华配音。\n------\n电影《铃芽之旅》的故事背景是什么?\n日本\n------\n谁担任电影《铃芽之旅》中岩户环的配音?\n深津绘里担任电影《铃芽之旅》中岩户环的配音。\n</Data>\n\n回答要求:\n- 如果你不清楚答案,你需要澄清。\n- 避免提及你是从 <Data></Data> 获取的知识。\n- 保持答案与 <Data></Data> 中描述的一致。\n- 使用 Markdown 语法优化回答格式。\n- 使用与问题相同的语言回答。\n\n问题:\"\"\"导演是谁\"\"\""
|
||||
"value": "导演是谁"
|
||||
},
|
||||
{
|
||||
"obj": "AI",
|
||||
"value": "电影《铃芽之旅》的导演是新海诚。"
|
||||
}
|
||||
],
|
||||
"contextTotalLen": 2,
|
||||
"runningTime": 1.32
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
|
||||
}'
|
||||
```
|
||||
|
||||
**responseData 完整字段说明:**
|
||||
|
||||
```ts
|
||||
type ResponseType = {
|
||||
moduleType: `${FlowNodeTypeEnum}`; // 模块类型
|
||||
moduleName: string; // 模块名
|
||||
moduleLogo?: string; // logo
|
||||
runningTime?: number; // 运行时间
|
||||
query?: string; // 用户问题/检索词
|
||||
textOutput?: string; // 文本输出
|
||||
|
||||
charsLength?: number; // 上下文总字数
|
||||
model?: string; // 使用到的模型
|
||||
contextTotalLen?: number; // 上下文总长度
|
||||
totalPoints?: number; // 总消耗AI积分
|
||||
|
||||
temperature?: number; // 温度
|
||||
maxToken?: number; // 模型的最大token
|
||||
quoteList?: SearchDataResponseItemType[]; // 引用列表
|
||||
historyPreview?: ChatItemType[]; // 上下文预览(历史记录会被裁剪)
|
||||
|
||||
similarity?: number; // 最低相关度
|
||||
limit?: number; // 引用上限token
|
||||
searchMode?: `${DatasetSearchModeEnum}`; // 搜索模式
|
||||
searchUsingReRank?: boolean; // 是否使用rerank
|
||||
extensionModel?: string; // 问题扩展模型
|
||||
extensionResult?: string; // 问题扩展结果
|
||||
extensionCharsLength?: number; // 问题扩展总字符长度
|
||||
|
||||
cqList?: ClassifyQuestionAgentItemType[]; // 分类问题列表
|
||||
cqResult?: string; // 分类问题结果
|
||||
|
||||
extractDescription?: string; // 内容提取描述
|
||||
extractResult?: Record<string, any>; // 内容提取结果
|
||||
|
||||
params?: Record<string, any>; // HTTP模块params
|
||||
body?: Record<string, any>; // HTTP模块body
|
||||
headers?: Record<string, any>; // HTTP模块headers
|
||||
httpResult?: Record<string, any>; // HTTP模块结果
|
||||
|
||||
pluginOutput?: Record<string, any>; // 插件输出
|
||||
pluginDetail?: ChatHistoryItemResType[]; // 插件详情
|
||||
|
||||
tfSwitchResult?: boolean; // 判断器结果
|
||||
}
|
||||
```
|
||||
|
||||
## 实践案例
|
||||
|
||||
|
@@ -15,13 +15,13 @@ weight: 831
|
||||
|
||||
1. 主要是修改模型的`functionCall`字段,改成`toolChoice`即可。设置为`true`的模型,会默认走 openai 的 tools 模式;未设置或设置为`false`的,会走提示词生成模式。
|
||||
|
||||
问题优化模型与内容提取模型使用同一组配置。
|
||||
问题补全模型与内容提取模型使用同一组配置。
|
||||
|
||||
2. 增加 `"ReRankModels": []`
|
||||
|
||||
## V4.6.5 功能介绍
|
||||
|
||||
1. 新增 - [问题优化模块](/docs/workflow/modules/coreferenceresolution/)
|
||||
1. 新增 - [问题补全模块](/docs/workflow/modules/coreferenceresolution/)
|
||||
2. 新增 - [文本编辑模块](/docs/workflow/modules/text_editor/)
|
||||
3. 新增 - [判断器模块](/docs/workflow/modules/tfswitch/)
|
||||
4. 新增 - [自定义反馈模块](/docs/workflow/modules/custom_feedback/)
|
||||
|
@@ -11,7 +11,7 @@ weight: 829
|
||||
|
||||
发起 1 个 HTTP 请求 ({{rootkey}} 替换成环境变量里的 `rootkey`,{{host}} 替换成自己域名)
|
||||
|
||||
1. https://xxxxx/api/admin/initv467
|
||||
1. https://xxxxx/api/admin/initv464
|
||||
|
||||
```bash
|
||||
curl --location --request POST 'https://{{host}}/api/admin/initv467' \
|
||||
|
@@ -36,7 +36,6 @@ mongo:
|
||||
cd 项目目录
|
||||
# 创建 mongo 密钥
|
||||
openssl rand -base64 756 > ./mongodb.key
|
||||
# 600不行可以用chmod 999
|
||||
chmod 600 ./mongodb.key
|
||||
chown 999:root ./mongodb.key
|
||||
# 重启 Mongo
|
||||
|
@@ -1,13 +0,0 @@
|
||||
---
|
||||
title: 'V4.6.9(进行中)'
|
||||
description: 'FastGPT V4.6.9更新说明'
|
||||
icon: 'upgrade'
|
||||
draft: false
|
||||
toc: true
|
||||
weight: 827
|
||||
---
|
||||
|
||||
|
||||
## V4.6.9 更新说明
|
||||
|
||||
1. 优化 - 重写了计量模式
|
@@ -135,7 +135,7 @@ export default async function (ctx: FunctionContext) {
|
||||
},
|
||||
{
|
||||
"key": "model",
|
||||
"type": "selectLLMModel",
|
||||
"type": "selectExtractModel",
|
||||
"valueType": "string",
|
||||
"label": "core.module.input.label.LLM",
|
||||
"required": true,
|
||||
@@ -264,7 +264,7 @@ export default async function (ctx: FunctionContext) {
|
||||
},
|
||||
{
|
||||
"key": "model",
|
||||
"type": "selectLLMModel",
|
||||
"type": "selectChatModel",
|
||||
"label": "core.module.input.label.aiModel",
|
||||
"required": true,
|
||||
"valueType": "string",
|
||||
@@ -635,7 +635,7 @@ export default async function (ctx: FunctionContext) {
|
||||
},
|
||||
{
|
||||
"key": "model",
|
||||
"type": "selectLLMModel",
|
||||
"type": "selectChatModel",
|
||||
"label": "core.module.input.label.aiModel",
|
||||
"required": true,
|
||||
"valueType": "string",
|
||||
|
@@ -139,7 +139,7 @@ HTTP 模块允许你调用任意 GET/POST 类型的 HTTP 接口,从而实现
|
||||
},
|
||||
{
|
||||
"key": "model",
|
||||
"type": "selectLLMModel",
|
||||
"type": "selectExtractModel",
|
||||
"valueType": "string",
|
||||
"label": "core.module.input.label.LLM",
|
||||
"required": true,
|
||||
@@ -401,7 +401,7 @@ HTTP 模块允许你调用任意 GET/POST 类型的 HTTP 接口,从而实现
|
||||
},
|
||||
{
|
||||
"key": "model",
|
||||
"type": "selectLLMModel",
|
||||
"type": "selectCQModel",
|
||||
"valueType": "string",
|
||||
"label": "core.module.input.label.Classify model",
|
||||
"required": true,
|
||||
@@ -614,7 +614,7 @@ HTTP 模块允许你调用任意 GET/POST 类型的 HTTP 接口,从而实现
|
||||
},
|
||||
{
|
||||
"key": "model",
|
||||
"type": "selectLLMModel",
|
||||
"type": "selectChatModel",
|
||||
"label": "core.module.input.label.aiModel",
|
||||
"required": true,
|
||||
"valueType": "string",
|
||||
@@ -835,7 +835,7 @@ HTTP 模块允许你调用任意 GET/POST 类型的 HTTP 接口,从而实现
|
||||
},
|
||||
{
|
||||
"key": "model",
|
||||
"type": "selectLLMModel",
|
||||
"type": "selectExtractModel",
|
||||
"valueType": "string",
|
||||
"label": "core.module.input.label.LLM",
|
||||
"required": true,
|
||||
|
@@ -1,6 +1,6 @@
|
||||
---
|
||||
title: "问题优化(已合并到知识库搜索)"
|
||||
description: "问题优化模块介绍和使用"
|
||||
title: "问题补全(已合并到知识库搜索)"
|
||||
description: "问题补全模块介绍和使用"
|
||||
icon: "input"
|
||||
draft: false
|
||||
toc: true
|
||||
@@ -23,7 +23,7 @@ weight: 364
|
||||
|
||||

|
||||
|
||||
用户在提问“第二点是什么”的时候,只会去知识库里查找“第二点是什么”,压根查不到内容。实际上需要查询的是“QA结构是什么”。因此我们需要引入一个【问题优化】模块,来对用户当前的问题进行补全,从而使得知识库搜索能够搜索到合适的内容。使用补全后效果如下:
|
||||
用户在提问“第二点是什么”的时候,只会去知识库里查找“第二点是什么”,压根查不到内容。实际上需要查询的是“QA结构是什么”。因此我们需要引入一个【问题补全】模块,来对用户当前的问题进行补全,从而使得知识库搜索能够搜索到合适的内容。使用补全后效果如下:
|
||||
|
||||

|
||||
|
||||
|
@@ -3,25 +3,11 @@ import { ErrType } from '../errorCode';
|
||||
/* team: 500000 */
|
||||
export enum TeamErrEnum {
|
||||
teamOverSize = 'teamOverSize',
|
||||
unAuthTeam = 'unAuthTeam',
|
||||
aiPointsNotEnough = 'aiPointsNotEnough',
|
||||
datasetSizeNotEnough = 'datasetSizeNotEnough',
|
||||
datasetAmountNotEnough = 'datasetAmountNotEnough',
|
||||
appAmountNotEnough = 'appAmountNotEnough',
|
||||
pluginAmountNotEnough = 'pluginAmountNotEnough',
|
||||
websiteSyncNotEnough = 'websiteSyncNotEnough',
|
||||
reRankNotEnough = 'reRankNotEnough'
|
||||
unAuthTeam = 'unAuthTeam'
|
||||
}
|
||||
const teamErr = [
|
||||
{ statusText: TeamErrEnum.teamOverSize, message: 'error.team.overSize' },
|
||||
{ statusText: TeamErrEnum.unAuthTeam, message: '无权操作该团队' },
|
||||
{ statusText: TeamErrEnum.aiPointsNotEnough, message: 'AI积分已用完~' },
|
||||
{ statusText: TeamErrEnum.datasetSizeNotEnough, message: '知识库容量不足,请先扩容~' },
|
||||
{ statusText: TeamErrEnum.datasetAmountNotEnough, message: '知识库数量已达上限~' },
|
||||
{ statusText: TeamErrEnum.appAmountNotEnough, message: '应用数量已达上限~' },
|
||||
{ statusText: TeamErrEnum.pluginAmountNotEnough, message: '插件数量已达上限~' },
|
||||
{ statusText: TeamErrEnum.websiteSyncNotEnough, message: '无权使用Web站点同步~' },
|
||||
{ statusText: TeamErrEnum.reRankNotEnough, message: '无权使用检索重排~' }
|
||||
{ statusText: TeamErrEnum.unAuthTeam, message: '无权操作该团队' }
|
||||
];
|
||||
export default teamErr.reduce((acc, cur, index) => {
|
||||
return {
|
||||
|
@@ -1,4 +0,0 @@
|
||||
export const formatNumber = (num: number, digit = 1e4) => Math.round(num * digit) / digit;
|
||||
|
||||
export const formatNumber2Million = (num: number) => Math.round(num / 1000000);
|
||||
export const formatNumber2Thousand = (num: number) => Math.round(num / 1000);
|
15
packages/global/core/ai/model.d.ts
vendored
@@ -6,7 +6,8 @@ export type LLMModelItemType = {
|
||||
quoteMaxToken: number;
|
||||
maxTemperature: number;
|
||||
|
||||
charsPointsPrice: number; // 1k chars=n points
|
||||
inputPrice: number;
|
||||
outputPrice: number;
|
||||
|
||||
censor?: boolean;
|
||||
vision?: boolean;
|
||||
@@ -26,7 +27,8 @@ export type VectorModelItemType = {
|
||||
model: string;
|
||||
name: string;
|
||||
defaultToken: number;
|
||||
charsPointsPrice: number;
|
||||
inputPrice: number;
|
||||
outputPrice: number;
|
||||
maxToken: number;
|
||||
weight: number;
|
||||
hidden?: boolean;
|
||||
@@ -36,7 +38,8 @@ export type VectorModelItemType = {
|
||||
export type ReRankModelItemType = {
|
||||
model: string;
|
||||
name: string;
|
||||
charsPointsPrice: number;
|
||||
inputPrice: number;
|
||||
outputPrice?: number;
|
||||
requestUrl?: string;
|
||||
requestAuth?: string;
|
||||
};
|
||||
@@ -44,12 +47,14 @@ export type ReRankModelItemType = {
|
||||
export type AudioSpeechModelType = {
|
||||
model: string;
|
||||
name: string;
|
||||
charsPointsPrice: number;
|
||||
inputPrice: number;
|
||||
outputPrice?: number;
|
||||
voices: { label: string; value: string; bufferId: string }[];
|
||||
};
|
||||
|
||||
export type WhisperModelType = {
|
||||
model: string;
|
||||
name: string;
|
||||
charsPointsPrice: number; // 60s = n points
|
||||
inputPrice: number;
|
||||
outputPrice?: number;
|
||||
};
|
||||
|
@@ -8,7 +8,8 @@ export const defaultQAModels: LLMModelItemType[] = [
|
||||
maxResponse: 16000,
|
||||
quoteMaxToken: 13000,
|
||||
maxTemperature: 1.2,
|
||||
charsPointsPrice: 0,
|
||||
inputPrice: 0,
|
||||
outputPrice: 0,
|
||||
censor: false,
|
||||
vision: false,
|
||||
datasetProcess: true,
|
||||
@@ -25,7 +26,8 @@ export const defaultVectorModels: VectorModelItemType[] = [
|
||||
{
|
||||
model: 'text-embedding-ada-002',
|
||||
name: 'Embedding-2',
|
||||
charsPointsPrice: 0,
|
||||
inputPrice: 0,
|
||||
outputPrice: 0,
|
||||
defaultToken: 500,
|
||||
maxToken: 3000,
|
||||
weight: 100
|
||||
|
1
packages/global/core/app/api.d.ts
vendored
@@ -17,7 +17,6 @@ export interface AppUpdateParams {
|
||||
intro?: string;
|
||||
modules?: AppSchema['modules'];
|
||||
permission?: AppSchema['permission'];
|
||||
teamTags?: AppSchema['teamTags'];
|
||||
}
|
||||
|
||||
export type FormatForm2ModulesProps = {
|
||||
|
3
packages/global/core/app/type.d.ts
vendored
@@ -5,7 +5,7 @@ import type { AIChatModuleProps, DatasetModuleProps } from '../module/node/type.
|
||||
import { VariableInputEnum } from '../module/constants';
|
||||
import { SelectedDatasetType } from '../module/api';
|
||||
import { DatasetSearchModeEnum } from '../dataset/constants';
|
||||
import { TeamTagsSchema as TeamTagsSchemaType } from '@fastgpt/global/support/user/team/type.d';
|
||||
|
||||
export interface AppSchema {
|
||||
_id: string;
|
||||
userId: string;
|
||||
@@ -20,7 +20,6 @@ export interface AppSchema {
|
||||
modules: ModuleItemType[];
|
||||
permission: `${PermissionTypeEnum}`;
|
||||
inited?: boolean;
|
||||
teamTags: [string];
|
||||
}
|
||||
|
||||
export type AppListItemType = {
|
||||
|
@@ -27,8 +27,7 @@ export enum ChatSourceEnum {
|
||||
test = 'test',
|
||||
online = 'online',
|
||||
share = 'share',
|
||||
api = 'api',
|
||||
team = 'team'
|
||||
api = 'api'
|
||||
}
|
||||
export const ChatSourceMap = {
|
||||
[ChatSourceEnum.test]: {
|
||||
@@ -42,9 +41,6 @@ export const ChatSourceMap = {
|
||||
},
|
||||
[ChatSourceEnum.api]: {
|
||||
name: 'core.chat.logs.api'
|
||||
},
|
||||
[ChatSourceEnum.team]: {
|
||||
name: 'core.chat.logs.team'
|
||||
}
|
||||
};
|
||||
|
||||
|
28
packages/global/core/chat/type.d.ts
vendored
@@ -4,7 +4,6 @@ import { ChatRoleEnum, ChatSourceEnum, ChatStatusEnum } from './constants';
|
||||
import { FlowNodeTypeEnum } from '../module/node/constant';
|
||||
import { ModuleOutputKeyEnum } from '../module/constants';
|
||||
import { AppSchema } from '../app/type';
|
||||
import type { AppSchema as AppType } from '@fastgpt/global/core/app/type.d';
|
||||
import { DatasetSearchModeEnum } from '../dataset/constants';
|
||||
|
||||
export type ChatSchema = {
|
||||
@@ -26,22 +25,6 @@ export type ChatSchema = {
|
||||
metadata?: Record<string, any>;
|
||||
};
|
||||
|
||||
export type teamInfoType = {
|
||||
avatar: string;
|
||||
balance: number;
|
||||
createTime: string;
|
||||
maxSize: number;
|
||||
name: string;
|
||||
ownerId: string;
|
||||
tagsUrl: string;
|
||||
_id: string;
|
||||
}
|
||||
|
||||
export type chatAppListSchema = {
|
||||
apps: Array<AppType>,
|
||||
teamInfo: teamInfoSchema
|
||||
}
|
||||
|
||||
export type ChatWithAppSchema = Omit<ChatSchema, 'appId'> & {
|
||||
appId: AppSchema;
|
||||
};
|
||||
@@ -105,15 +88,15 @@ export type ChatHistoryItemType = HistoryItemType & {
|
||||
export type moduleDispatchResType = {
|
||||
// common
|
||||
moduleLogo?: string;
|
||||
price?: number;
|
||||
runningTime?: number;
|
||||
query?: string;
|
||||
textOutput?: string;
|
||||
|
||||
// bill
|
||||
inputTokens?: number;
|
||||
outputTokens?: number;
|
||||
charsLength?: number;
|
||||
model?: string;
|
||||
query?: string;
|
||||
contextTotalLen?: number;
|
||||
totalPoints?: number;
|
||||
textOutput?: string;
|
||||
|
||||
// chat
|
||||
temperature?: number;
|
||||
@@ -128,7 +111,6 @@ export type moduleDispatchResType = {
|
||||
searchUsingReRank?: boolean;
|
||||
extensionModel?: string;
|
||||
extensionResult?: string;
|
||||
extensionCharsLength?: number;
|
||||
|
||||
// cq
|
||||
cqList?: ClassifyQuestionAgentItemType[];
|
||||
|
@@ -71,6 +71,30 @@ export const DatasetCollectionSyncResultMap = {
|
||||
};
|
||||
|
||||
/* ------------ data -------------- */
|
||||
export enum DatasetDataIndexTypeEnum {
|
||||
chunk = 'chunk',
|
||||
qa = 'qa',
|
||||
summary = 'summary',
|
||||
hypothetical = 'hypothetical',
|
||||
custom = 'custom'
|
||||
}
|
||||
export const DatasetDataIndexTypeMap = {
|
||||
[DatasetDataIndexTypeEnum.chunk]: {
|
||||
name: 'dataset.data.indexes.chunk'
|
||||
},
|
||||
[DatasetDataIndexTypeEnum.summary]: {
|
||||
name: 'dataset.data.indexes.summary'
|
||||
},
|
||||
[DatasetDataIndexTypeEnum.hypothetical]: {
|
||||
name: 'dataset.data.indexes.hypothetical'
|
||||
},
|
||||
[DatasetDataIndexTypeEnum.qa]: {
|
||||
name: 'dataset.data.indexes.qa'
|
||||
},
|
||||
[DatasetDataIndexTypeEnum.custom]: {
|
||||
name: 'dataset.data.indexes.custom'
|
||||
}
|
||||
};
|
||||
|
||||
/* ------------ training -------------- */
|
||||
export enum TrainingModeEnum {
|
||||
|
5
packages/global/core/dataset/type.d.ts
vendored
@@ -3,6 +3,7 @@ import { PermissionTypeEnum } from '../../support/permission/constant';
|
||||
import { PushDatasetDataChunkProps } from './api';
|
||||
import {
|
||||
DatasetCollectionTypeEnum,
|
||||
DatasetDataIndexTypeEnum,
|
||||
DatasetStatusEnum,
|
||||
DatasetTypeEnum,
|
||||
SearchScoreTypeEnum,
|
||||
@@ -63,6 +64,7 @@ export type DatasetCollectionSchemaType = {
|
||||
export type DatasetDataIndexItemType = {
|
||||
defaultIndex: boolean;
|
||||
dataId: string; // pg data id
|
||||
type: `${DatasetDataIndexTypeEnum}`;
|
||||
text: string;
|
||||
};
|
||||
export type DatasetDataSchemaType = {
|
||||
@@ -140,7 +142,6 @@ export type DatasetCollectionItemType = CollectionWithDatasetType & {
|
||||
/* ================= data ===================== */
|
||||
export type DatasetDataItemType = {
|
||||
id: string;
|
||||
teamId: string;
|
||||
datasetId: string;
|
||||
collectionId: string;
|
||||
sourceName: string;
|
||||
@@ -172,7 +173,7 @@ export type DatasetFileSchema = {
|
||||
/* ============= search =============== */
|
||||
export type SearchDataResponseItemType = Omit<
|
||||
DatasetDataItemType,
|
||||
'teamId' | 'indexes' | 'isOwner' | 'canWrite'
|
||||
'indexes' | 'isOwner' | 'canWrite'
|
||||
> & {
|
||||
score: { type: `${SearchScoreTypeEnum}`; value: number; index: number }[];
|
||||
// score: number;
|
||||
|
@@ -1,4 +1,4 @@
|
||||
import { TrainingModeEnum, DatasetCollectionTypeEnum } from './constants';
|
||||
import { TrainingModeEnum, DatasetCollectionTypeEnum, DatasetDataIndexTypeEnum } from './constants';
|
||||
import { getFileIcon } from '../../common/file/icon';
|
||||
import { strIsLink } from '../../common/string/tools';
|
||||
|
||||
@@ -41,6 +41,7 @@ export function getDefaultIndex(props?: { q?: string; a?: string; dataId?: strin
|
||||
const qaStr = `${q}\n${a}`.trim();
|
||||
return {
|
||||
defaultIndex: true,
|
||||
type: a ? DatasetDataIndexTypeEnum.qa : DatasetDataIndexTypeEnum.chunk,
|
||||
text: a ? qaStr : q,
|
||||
dataId
|
||||
};
|
||||
|
@@ -89,10 +89,9 @@ export enum ModuleInputKeyEnum {
|
||||
|
||||
export enum ModuleOutputKeyEnum {
|
||||
// common
|
||||
responseData = 'responseData',
|
||||
moduleDispatchBills = 'moduleDispatchBills',
|
||||
userChatInput = 'userChatInput',
|
||||
finish = 'finish',
|
||||
responseData = 'responseData',
|
||||
history = 'history',
|
||||
answerText = 'answerText', // answer module text key
|
||||
success = 'success',
|
||||
|
@@ -20,7 +20,9 @@ export enum FlowNodeInputTypeEnum {
|
||||
aiSettings = 'aiSettings',
|
||||
|
||||
// ai model select
|
||||
selectLLMModel = 'selectLLMModel',
|
||||
selectChatModel = 'selectChatModel',
|
||||
selectCQModel = 'selectCQModel',
|
||||
selectExtractModel = 'selectExtractModel',
|
||||
|
||||
// dataset special input
|
||||
selectDataset = 'selectDataset',
|
||||
@@ -56,7 +58,7 @@ export enum FlowNodeTypeEnum {
|
||||
pluginModule = 'pluginModule',
|
||||
pluginInput = 'pluginInput',
|
||||
pluginOutput = 'pluginOutput',
|
||||
queryExtension = 'cfr'
|
||||
cfr = 'cfr'
|
||||
|
||||
// abandon
|
||||
}
|
||||
|
@@ -31,7 +31,7 @@ export const AiChatModule: FlowModuleTemplateType = {
|
||||
Input_Template_Switch,
|
||||
{
|
||||
key: ModuleInputKeyEnum.aiModel,
|
||||
type: FlowNodeInputTypeEnum.selectLLMModel,
|
||||
type: FlowNodeInputTypeEnum.selectChatModel,
|
||||
label: 'core.module.input.label.aiModel',
|
||||
required: true,
|
||||
valueType: ModuleIOValueTypeEnum.string,
|
||||
|
@@ -24,7 +24,7 @@ export const ClassifyQuestionModule: FlowModuleTemplateType = {
|
||||
Input_Template_Switch,
|
||||
{
|
||||
key: ModuleInputKeyEnum.aiModel,
|
||||
type: FlowNodeInputTypeEnum.selectLLMModel,
|
||||
type: FlowNodeInputTypeEnum.selectCQModel,
|
||||
valueType: ModuleIOValueTypeEnum.string,
|
||||
label: 'core.module.input.label.Classify model',
|
||||
required: true,
|
||||
|
@@ -24,7 +24,7 @@ export const ContextExtractModule: FlowModuleTemplateType = {
|
||||
Input_Template_Switch,
|
||||
{
|
||||
key: ModuleInputKeyEnum.aiModel,
|
||||
type: FlowNodeInputTypeEnum.selectLLMModel,
|
||||
type: FlowNodeInputTypeEnum.selectExtractModel,
|
||||
valueType: ModuleIOValueTypeEnum.string,
|
||||
label: 'core.module.input.label.LLM',
|
||||
required: true,
|
||||
|
@@ -3,7 +3,7 @@ import {
|
||||
FlowNodeOutputTypeEnum,
|
||||
FlowNodeTypeEnum
|
||||
} from '../../node/constant';
|
||||
import { FlowModuleTemplateType } from '../../type';
|
||||
import { FlowModuleTemplateType } from '../../type.d';
|
||||
import {
|
||||
ModuleIOValueTypeEnum,
|
||||
ModuleInputKeyEnum,
|
||||
@@ -17,19 +17,19 @@ import {
|
||||
} from '../input';
|
||||
import { Output_Template_UserChatInput } from '../output';
|
||||
|
||||
export const AiQueryExtension: FlowModuleTemplateType = {
|
||||
export const AiCFR: FlowModuleTemplateType = {
|
||||
id: FlowNodeTypeEnum.chatNode,
|
||||
templateType: ModuleTemplateTypeEnum.other,
|
||||
flowType: FlowNodeTypeEnum.queryExtension,
|
||||
flowType: FlowNodeTypeEnum.cfr,
|
||||
avatar: '/imgs/module/cfr.svg',
|
||||
name: 'core.module.template.Query extension',
|
||||
intro: 'core.module.template.Query extension intro',
|
||||
intro: '该模块已合并到知识库搜索参数中,无需单独使用。模块将于2024/3/31弃用,请尽快修改。',
|
||||
showStatus: true,
|
||||
inputs: [
|
||||
Input_Template_Switch,
|
||||
{
|
||||
key: ModuleInputKeyEnum.aiModel,
|
||||
type: FlowNodeInputTypeEnum.selectLLMModel,
|
||||
type: FlowNodeInputTypeEnum.selectExtractModel,
|
||||
label: 'core.module.input.label.aiModel',
|
||||
required: true,
|
||||
valueType: ModuleIOValueTypeEnum.string,
|
||||
@@ -39,7 +39,7 @@ export const AiQueryExtension: FlowModuleTemplateType = {
|
||||
{
|
||||
key: ModuleInputKeyEnum.aiSystemPrompt,
|
||||
type: FlowNodeInputTypeEnum.textarea,
|
||||
label: 'core.app.edit.Query extension background prompt',
|
||||
label: 'core.module.input.label.Background',
|
||||
max: 300,
|
||||
valueType: ModuleIOValueTypeEnum.string,
|
||||
description: 'core.app.edit.Query extension background tip',
|
||||
@@ -54,8 +54,7 @@ export const AiQueryExtension: FlowModuleTemplateType = {
|
||||
Output_Template_UserChatInput,
|
||||
{
|
||||
key: ModuleOutputKeyEnum.text,
|
||||
label: 'core.module.output.label.query extension result',
|
||||
description: 'core.module.output.description.query extension result',
|
||||
label: 'core.module.output.label.cfr result',
|
||||
valueType: ModuleIOValueTypeEnum.string,
|
||||
type: FlowNodeOutputTypeEnum.source,
|
||||
targets: []
|
19
packages/global/core/module/type.d.ts
vendored
@@ -1,14 +1,6 @@
|
||||
import { FlowNodeTypeEnum } from './node/constant';
|
||||
import {
|
||||
ModuleIOValueTypeEnum,
|
||||
ModuleOutputKeyEnum,
|
||||
ModuleTemplateTypeEnum,
|
||||
VariableInputEnum
|
||||
} from './constants';
|
||||
import { ModuleIOValueTypeEnum, ModuleTemplateTypeEnum, VariableInputEnum } from './constants';
|
||||
import { FlowNodeInputItemType, FlowNodeOutputItemType } from './node/type';
|
||||
import { UserModelSchema } from 'support/user/type';
|
||||
import { moduleDispatchResType } from '..//chat/type';
|
||||
import { ChatModuleBillType } from '../../support/wallet/bill/type';
|
||||
|
||||
export type FlowModuleTemplateType = {
|
||||
id: string; // module id, unique
|
||||
@@ -113,7 +105,7 @@ export type ChatDispatchProps = {
|
||||
mode: 'test' | 'chat';
|
||||
teamId: string;
|
||||
tmbId: string;
|
||||
user: UserModelSchema;
|
||||
user: UserType;
|
||||
appId: string;
|
||||
chatId?: string;
|
||||
responseChatItemId?: string;
|
||||
@@ -124,10 +116,7 @@ export type ChatDispatchProps = {
|
||||
};
|
||||
|
||||
export type ModuleDispatchProps<T> = ChatDispatchProps & {
|
||||
module: RunningModuleItemType;
|
||||
outputs: RunningModuleItemType['outputs'];
|
||||
inputs: RunningModuleItemType['inputs'];
|
||||
params: T;
|
||||
};
|
||||
export type ModuleDispatchResponse<T> = T & {
|
||||
[ModuleOutputKeyEnum.responseData]?: moduleDispatchResType;
|
||||
[ModuleOutputKeyEnum.moduleDispatchBills]?: ChatModuleBillType[];
|
||||
};
|
||||
|
5
packages/global/support/openapi/type.d.ts
vendored
@@ -1,5 +1,6 @@
|
||||
export type OpenApiSchema = {
|
||||
_id: string;
|
||||
userId: string;
|
||||
teamId: string;
|
||||
tmbId: string;
|
||||
createTime: Date;
|
||||
@@ -7,9 +8,9 @@ export type OpenApiSchema = {
|
||||
apiKey: string;
|
||||
appId?: string;
|
||||
name: string;
|
||||
usagePoints: number;
|
||||
usage: number;
|
||||
limit?: {
|
||||
expiredTime?: Date;
|
||||
maxUsagePoints: number;
|
||||
credit?: number;
|
||||
};
|
||||
};
|
||||
|
2
packages/global/support/outLink/api.d.ts
vendored
@@ -1,5 +1,5 @@
|
||||
import type { HistoryItemType, ChatSiteItemType } from '../../core/chat/type.d';
|
||||
import { OutLinkSchema } from './type.d';
|
||||
import { OutLinkSchema } from '@fastgpt/global/support/outLink/type';
|
||||
|
||||
export type AuthOutLinkInitProps = {
|
||||
outLinkUid: string;
|
||||
|
4
packages/global/support/outLink/type.d.ts
vendored
@@ -7,14 +7,14 @@ export type OutLinkSchema = {
|
||||
tmbId: string;
|
||||
appId: string;
|
||||
name: string;
|
||||
usagePoints: number;
|
||||
total: number;
|
||||
lastTime: Date;
|
||||
type: `${OutLinkTypeEnum}`;
|
||||
responseDetail: boolean;
|
||||
limit?: {
|
||||
expiredTime?: Date;
|
||||
QPM: number;
|
||||
maxUsagePoints: number;
|
||||
credit: number;
|
||||
hookUrl?: string;
|
||||
};
|
||||
};
|
||||
|
1
packages/global/support/permission/type.d.ts
vendored
@@ -1,6 +1,7 @@
|
||||
import { AuthUserTypeEnum } from './constant';
|
||||
|
||||
export type AuthResponseType = {
|
||||
userId: string;
|
||||
teamId: string;
|
||||
tmbId: string;
|
||||
isOwner: boolean;
|
||||
|
@@ -1,6 +1,5 @@
|
||||
export const TeamCollectionName = 'teams';
|
||||
export const TeamMemberCollectionName = 'team.members';
|
||||
export const TeamTagsCollectionName = 'team.tags';
|
||||
|
||||
export enum TeamMemberRoleEnum {
|
||||
owner = 'owner',
|
||||
|
@@ -15,7 +15,6 @@ export type UpdateTeamProps = {
|
||||
teamId: string;
|
||||
name?: string;
|
||||
avatar?: string;
|
||||
tagsUrl?: string;
|
||||
};
|
||||
|
||||
/* ------------- member ----------- */
|
||||
|
18
packages/global/support/user/team/type.d.ts
vendored
@@ -9,23 +9,11 @@ export type TeamSchema = {
|
||||
createTime: Date;
|
||||
balance: number;
|
||||
maxSize: number;
|
||||
tagsUrl: string;
|
||||
limit: {
|
||||
lastExportDatasetTime: Date;
|
||||
lastWebsiteSyncTime: Date;
|
||||
};
|
||||
};
|
||||
export type tagsType = {
|
||||
label: string,
|
||||
key: string
|
||||
}
|
||||
export type TeamTagsSchema = {
|
||||
_id: string;
|
||||
label: string;
|
||||
teamId: string;
|
||||
key: string;
|
||||
createTime: Date;
|
||||
};
|
||||
|
||||
export type TeamMemberSchema = {
|
||||
_id: string;
|
||||
@@ -38,13 +26,13 @@ export type TeamMemberSchema = {
|
||||
defaultTeam: boolean;
|
||||
};
|
||||
|
||||
export type TeamMemberWithUserSchema = Omit<TeamMemberSchema, 'userId'> & {
|
||||
export type TeamMemberWithUserSchema = TeamMemberSchema & {
|
||||
userId: UserModelSchema;
|
||||
};
|
||||
export type TeamMemberWithTeamSchema = Omit<TeamMemberSchema, 'teamId'> & {
|
||||
export type TeamMemberWithTeamSchema = TeamMemberSchema & {
|
||||
teamId: TeamSchema;
|
||||
};
|
||||
export type TeamMemberWithTeamAndUserSchema = Omit<TeamMemberWithTeamSchema, 'userId'> & {
|
||||
export type TeamMemberWithTeamAndUserSchema = TeamMemberWithTeamSchema & {
|
||||
userId: UserModelSchema;
|
||||
};
|
||||
|
||||
|
1
packages/global/support/user/type.d.ts
vendored
@@ -29,5 +29,4 @@ export type UserType = {
|
||||
promotionRate: UserModelSchema['promotionRate'];
|
||||
openaiAccount: UserModelSchema['openaiAccount'];
|
||||
team: TeamItemType;
|
||||
standardInfo?: standardInfoType;
|
||||
};
|
||||
|
37
packages/global/support/wallet/bill/api.d.ts
vendored
@@ -1,18 +1,25 @@
|
||||
import { BillTypeEnum } from './constants';
|
||||
import { BillSourceEnum } from './constants';
|
||||
import { BillListItemCountType, BillListItemType } from './type';
|
||||
|
||||
export type CreateTrainingBillProps = {
|
||||
name: string;
|
||||
datasetId: string;
|
||||
};
|
||||
|
||||
export type ConcatBillProps = BillListItemCountType & {
|
||||
teamId: string;
|
||||
tmbId: string;
|
||||
billId?: string;
|
||||
total: number;
|
||||
listIndex?: number;
|
||||
};
|
||||
|
||||
export type CreateBillProps = {
|
||||
type: `${BillTypeEnum}`;
|
||||
|
||||
// balance
|
||||
balance?: number; // read
|
||||
|
||||
month?: number;
|
||||
// extra dataset size
|
||||
extraDatasetSize?: number; // 1k
|
||||
extraPoints?: number; // 100w
|
||||
};
|
||||
export type CreateBillResponse = {
|
||||
billId: string;
|
||||
codeUrl: string;
|
||||
readPrice: number;
|
||||
teamId: string;
|
||||
tmbId: string;
|
||||
appName: string;
|
||||
appId?: string;
|
||||
total: number;
|
||||
source: `${BillSourceEnum}`;
|
||||
list: BillListItemType[];
|
||||
};
|
||||
|
@@ -1,57 +1,34 @@
|
||||
export enum BillTypeEnum {
|
||||
balance = 'balance',
|
||||
// model price: xxx/1k tokens
|
||||
// ¥1 = 100000.
|
||||
export const PRICE_SCALE = 100000;
|
||||
|
||||
export enum BillSourceEnum {
|
||||
fastgpt = 'fastgpt',
|
||||
api = 'api',
|
||||
shareLink = 'shareLink',
|
||||
training = 'training',
|
||||
|
||||
standSubPlan = 'standSubPlan',
|
||||
extraDatasetSub = 'extraDatasetSub',
|
||||
extraPoints = 'extraPoints'
|
||||
extraDatasetSub = 'extraDatasetSub'
|
||||
}
|
||||
export const billTypeMap = {
|
||||
[BillTypeEnum.balance]: {
|
||||
label: 'support.wallet.subscription.type.balance'
|
||||
|
||||
export const BillSourceMap = {
|
||||
[BillSourceEnum.fastgpt]: {
|
||||
label: '在线使用'
|
||||
},
|
||||
[BillTypeEnum.standSubPlan]: {
|
||||
[BillSourceEnum.api]: {
|
||||
label: 'Api'
|
||||
},
|
||||
[BillSourceEnum.shareLink]: {
|
||||
label: '免登录链接'
|
||||
},
|
||||
[BillSourceEnum.training]: {
|
||||
label: 'dataset.Training Name'
|
||||
},
|
||||
[BillSourceEnum.standSubPlan]: {
|
||||
label: 'support.wallet.subscription.type.standard'
|
||||
},
|
||||
[BillTypeEnum.extraDatasetSub]: {
|
||||
[BillSourceEnum.extraDatasetSub]: {
|
||||
label: 'support.wallet.subscription.type.extraDatasetSize'
|
||||
},
|
||||
[BillTypeEnum.extraPoints]: {
|
||||
label: 'support.wallet.subscription.type.extraPoints'
|
||||
}
|
||||
};
|
||||
|
||||
export enum BillStatusEnum {
|
||||
SUCCESS = 'SUCCESS',
|
||||
REFUND = 'REFUND',
|
||||
NOTPAY = 'NOTPAY',
|
||||
CLOSED = 'CLOSED'
|
||||
}
|
||||
export const billStatusMap = {
|
||||
[BillStatusEnum.SUCCESS]: {
|
||||
label: 'support.wallet.bill.status.success'
|
||||
},
|
||||
[BillStatusEnum.REFUND]: {
|
||||
label: 'support.wallet.bill.status.refund'
|
||||
},
|
||||
[BillStatusEnum.NOTPAY]: {
|
||||
label: 'support.wallet.bill.status.notpay'
|
||||
},
|
||||
[BillStatusEnum.CLOSED]: {
|
||||
label: 'support.wallet.bill.status.closed'
|
||||
}
|
||||
};
|
||||
|
||||
export enum BillPayWayEnum {
|
||||
balance = 'balance',
|
||||
wx = 'wx'
|
||||
}
|
||||
export const billPayWayMap = {
|
||||
[BillPayWayEnum.balance]: {
|
||||
label: 'support.wallet.bill.payWay.balance'
|
||||
},
|
||||
[BillPayWayEnum.wx]: {
|
||||
label: 'support.wallet.bill.payWay.wx'
|
||||
}
|
||||
};
|
||||
|
||||
export const SUB_DATASET_SIZE_RATE = 1000;
|
||||
export const SUB_EXTRA_POINT_RATE = 1000000;
|
||||
|
26
packages/global/support/wallet/bill/tools.ts
Normal file
@@ -0,0 +1,26 @@
|
||||
/* bill common */
|
||||
import { PRICE_SCALE } from './constants';
|
||||
import { BillSourceEnum } from './constants';
|
||||
import { AuthUserTypeEnum } from '../../permission/constant';
|
||||
|
||||
/**
|
||||
* dataset price / PRICE_SCALE = real price
|
||||
*/
|
||||
export const formatStorePrice2Read = (val = 0, multiple = 1) => {
|
||||
return Number(((val / PRICE_SCALE) * multiple).toFixed(10));
|
||||
};
|
||||
export const formatModelPrice2Read = (val = 0) => {
|
||||
return Number((val / 1000).toFixed(10));
|
||||
};
|
||||
|
||||
export const getBillSourceByAuthType = ({
|
||||
shareId,
|
||||
authType
|
||||
}: {
|
||||
shareId?: string;
|
||||
authType?: `${AuthUserTypeEnum}`;
|
||||
}) => {
|
||||
if (shareId) return BillSourceEnum.shareLink;
|
||||
if (authType === AuthUserTypeEnum.apikey) return BillSourceEnum.api;
|
||||
return BillSourceEnum.fastgpt;
|
||||
};
|
56
packages/global/support/wallet/bill/type.d.ts
vendored
@@ -1,29 +1,35 @@
|
||||
import { StandardSubLevelEnum, SubModeEnum, SubTypeEnum } from '../sub/constants';
|
||||
import { BillPayWayEnum, BillTypeEnum } from './constants';
|
||||
import { CreateBillProps } from './api';
|
||||
import { BillSourceEnum } from './constants';
|
||||
|
||||
export type BillSchemaType = {
|
||||
_id: string;
|
||||
userId: string;
|
||||
teamId: string;
|
||||
tmbId: string;
|
||||
createTime: Date;
|
||||
orderId: string;
|
||||
status: 'SUCCESS' | 'REFUND' | 'NOTPAY' | 'CLOSED';
|
||||
type: `${BillTypeEnum}`;
|
||||
price: number;
|
||||
metadata: {
|
||||
payWay: `${BillPayWayEnum}`;
|
||||
subMode?: `${SubModeEnum}`;
|
||||
standSubLevel?: `${StandardSubLevelEnum}`;
|
||||
month?: number;
|
||||
datasetSize?: number;
|
||||
extraPoints?: number;
|
||||
};
|
||||
export type BillListItemCountType = {
|
||||
inputTokens?: number;
|
||||
outputTokens?: number;
|
||||
charsLength?: number;
|
||||
duration?: number;
|
||||
|
||||
// sub
|
||||
datasetSize?: number;
|
||||
|
||||
// abandon
|
||||
tokenLen?: number;
|
||||
};
|
||||
|
||||
export type ChatModuleBillType = {
|
||||
totalPoints: number;
|
||||
export type BillListItemType = BillListItemCountType & {
|
||||
moduleName: string;
|
||||
model: string;
|
||||
charsLength: number;
|
||||
amount: number;
|
||||
model?: string;
|
||||
};
|
||||
|
||||
export type BillSchema = CreateBillProps & {
|
||||
_id: string;
|
||||
time: Date;
|
||||
};
|
||||
|
||||
export type BillItemType = {
|
||||
id: string;
|
||||
// memberName: string;
|
||||
time: Date;
|
||||
appName: string;
|
||||
source: BillSchema['source'];
|
||||
total: number;
|
||||
list: BillSchema['list'];
|
||||
};
|
||||
|
@@ -1,3 +0,0 @@
|
||||
// model price: xxx/1k tokens
|
||||
// ¥1 = 100000.
|
||||
export const PRICE_SCALE = 100000;
|
41
packages/global/support/wallet/pay/constants.ts
Normal file
@@ -0,0 +1,41 @@
|
||||
export enum PayTypeEnum {
|
||||
balance = 'balance',
|
||||
subStandard = 'subStandard',
|
||||
subExtraDatasetSize = 'subExtraDatasetSize',
|
||||
subExtraPoints = 'subExtraPoints'
|
||||
}
|
||||
export const payTypeMap = {
|
||||
[PayTypeEnum.balance]: {
|
||||
label: 'support.user.team.pay.type.balance'
|
||||
},
|
||||
[PayTypeEnum.subStandard]: {
|
||||
label: 'support.wallet.subscription.type.standard'
|
||||
},
|
||||
[PayTypeEnum.subExtraDatasetSize]: {
|
||||
label: 'support.wallet.subscription.type.extraDatasetSize'
|
||||
},
|
||||
[PayTypeEnum.subExtraPoints]: {
|
||||
label: 'support.wallet.subscription.type.extraPoints'
|
||||
}
|
||||
};
|
||||
|
||||
export enum PayStatusEnum {
|
||||
SUCCESS = 'SUCCESS',
|
||||
REFUND = 'REFUND',
|
||||
NOTPAY = 'NOTPAY',
|
||||
CLOSED = 'CLOSED'
|
||||
}
|
||||
export const payStatusMap = {
|
||||
[PayStatusEnum.SUCCESS]: {
|
||||
label: 'support.user.team.pay.status.success'
|
||||
},
|
||||
[PayStatusEnum.REFUND]: {
|
||||
label: 'support.user.team.pay.status.refund'
|
||||
},
|
||||
[PayStatusEnum.NOTPAY]: {
|
||||
label: 'support.user.team.pay.status.notpay'
|
||||
},
|
||||
[PayStatusEnum.CLOSED]: {
|
||||
label: 'support.user.team.pay.status.closed'
|
||||
}
|
||||
};
|
18
packages/global/support/wallet/pay/type.d.ts
vendored
Normal file
@@ -0,0 +1,18 @@
|
||||
import { SubModeEnum, SubTypeEnum } from '../sub/constants';
|
||||
import { PayTypeEnum } from './constants';
|
||||
|
||||
export type PaySchema = {
|
||||
_id: string;
|
||||
userId: string;
|
||||
teamId: string;
|
||||
tmbId: string;
|
||||
createTime: Date;
|
||||
orderId: string;
|
||||
status: 'SUCCESS' | 'REFUND' | 'NOTPAY' | 'CLOSED';
|
||||
type: `${PayType}`;
|
||||
|
||||
price: number;
|
||||
payWay: 'balance' | 'wx';
|
||||
|
||||
subMetadata: {};
|
||||
};
|
14
packages/global/support/wallet/sub/api.d.ts
vendored
@@ -1,14 +1,26 @@
|
||||
import { StandardSubLevelEnum, SubModeEnum } from './constants';
|
||||
import { TeamSubSchema } from './type.d';
|
||||
|
||||
export type SubDatasetSizeParams = {
|
||||
size: number;
|
||||
};
|
||||
export type StandardSubPlanParams = {
|
||||
level: `${StandardSubLevelEnum}`;
|
||||
mode: `${SubModeEnum}`;
|
||||
};
|
||||
|
||||
export type SubDatasetSizePreviewCheckResponse = {
|
||||
payForNewSub: boolean; // Does this change require payment
|
||||
newSubSize: number; // new sub dataset size
|
||||
alreadySubSize: number; // old sub dataset size
|
||||
payPrice: number; // this change require payment
|
||||
newPlanPrice: number; // the new sub price
|
||||
newSubStartTime: Date;
|
||||
newSubExpiredTime: Date;
|
||||
balanceEnough: boolean; // team balance is enough
|
||||
};
|
||||
export type StandardSubPlanUpdateResponse = {
|
||||
balanceEnough: boolean; // team balance is enough
|
||||
teamBalance: number;
|
||||
payPrice?: number;
|
||||
planPrice: number;
|
||||
planPointPrice: number;
|
||||
|
@@ -1,3 +1,5 @@
|
||||
export const POINTS_SCALE = 10000;
|
||||
|
||||
export enum SubTypeEnum {
|
||||
standard = 'standard',
|
||||
extraDatasetSize = 'extraDatasetSize',
|
||||
@@ -17,16 +19,20 @@ export const subTypeMap = {
|
||||
|
||||
export enum SubStatusEnum {
|
||||
active = 'active',
|
||||
expired = 'expired'
|
||||
canceled = 'canceled'
|
||||
}
|
||||
export const subStatusMap = {
|
||||
[SubStatusEnum.active]: {
|
||||
label: 'support.wallet.subscription.status.active'
|
||||
},
|
||||
[SubStatusEnum.expired]: {
|
||||
[SubStatusEnum.canceled]: {
|
||||
label: 'support.wallet.subscription.status.canceled'
|
||||
}
|
||||
};
|
||||
export const subSelectMap = {
|
||||
true: SubStatusEnum.active,
|
||||
false: SubStatusEnum.canceled
|
||||
};
|
||||
|
||||
export enum SubModeEnum {
|
||||
month = 'month',
|
||||
@@ -34,11 +40,11 @@ export enum SubModeEnum {
|
||||
}
|
||||
export const subModeMap = {
|
||||
[SubModeEnum.month]: {
|
||||
label: 'support.wallet.subscription.mode.Month',
|
||||
label: 'support.wallet.subscription.mode.month',
|
||||
durationMonth: 1
|
||||
},
|
||||
[SubModeEnum.year]: {
|
||||
label: 'support.wallet.subscription.mode.Year',
|
||||
label: 'support.wallet.subscription.mode.year',
|
||||
durationMonth: 12
|
||||
}
|
||||
};
|
||||
@@ -57,7 +63,7 @@ export const standardSubLevelMap = {
|
||||
},
|
||||
[StandardSubLevelEnum.experience]: {
|
||||
label: 'support.wallet.subscription.standardSubLevel.experience',
|
||||
desc: ''
|
||||
desc: 'support.wallet.subscription.standardSubLevel.experience desc'
|
||||
},
|
||||
[StandardSubLevelEnum.team]: {
|
||||
label: 'support.wallet.subscription.standardSubLevel.team',
|
||||
|
43
packages/global/support/wallet/sub/type.d.ts
vendored
@@ -2,19 +2,19 @@ import { StandardSubLevelEnum, SubModeEnum, SubStatusEnum, SubTypeEnum } from '.
|
||||
|
||||
// Content of plan
|
||||
export type TeamStandardSubPlanItemType = {
|
||||
price: number; // read price / month
|
||||
pointPrice: number; // read price/ one thousand
|
||||
totalPoints: number; // n
|
||||
price: number; // read price
|
||||
pointPrice: number; // read price/ one ten thousand
|
||||
maxTeamMember: number;
|
||||
maxAppAmount: number; // max app or plugin amount
|
||||
maxDatasetAmount: number;
|
||||
chatHistoryStoreDuration: number; // n day
|
||||
maxDatasetSize: number;
|
||||
customApiKey: boolean;
|
||||
customCopyright: boolean; // feature
|
||||
websiteSyncInterval: number; // n hours
|
||||
trainingWeight: number; // 1~4
|
||||
permissionCustomApiKey: boolean;
|
||||
permissionCustomCopyright: boolean; // feature
|
||||
permissionWebsiteSync: boolean;
|
||||
permissionReRank: boolean;
|
||||
reRankWeight: number; // 1~4
|
||||
totalPoints: number; // n ten thousand
|
||||
};
|
||||
|
||||
export type StandSubPlanLevelMapType = Record<
|
||||
@@ -27,9 +27,6 @@ export type SubPlanType = {
|
||||
[SubTypeEnum.extraDatasetSize]: {
|
||||
price: number;
|
||||
};
|
||||
[SubTypeEnum.extraPoints]: {
|
||||
price: number;
|
||||
};
|
||||
};
|
||||
|
||||
export type TeamSubSchema = {
|
||||
@@ -37,32 +34,40 @@ export type TeamSubSchema = {
|
||||
teamId: string;
|
||||
type: `${SubTypeEnum}`;
|
||||
status: `${SubStatusEnum}`;
|
||||
currentMode: `${SubModeEnum}`;
|
||||
nextMode: `${SubModeEnum}`;
|
||||
startTime: Date;
|
||||
expiredTime: Date;
|
||||
price: number;
|
||||
|
||||
currentMode: `${SubModeEnum}`;
|
||||
nextMode: `${SubModeEnum}`;
|
||||
currentSubLevel: `${StandardSubLevelEnum}`;
|
||||
nextSubLevel: `${StandardSubLevelEnum}`;
|
||||
|
||||
pointPrice: number;
|
||||
totalPoints: number;
|
||||
surplusPoints: number;
|
||||
|
||||
currentExtraDatasetSize: number;
|
||||
nextExtraDatasetSize: number;
|
||||
|
||||
currentExtraPoints: number;
|
||||
nextExtraPoints: number;
|
||||
|
||||
surplusPoints: number;
|
||||
|
||||
// abandon
|
||||
datasetStoreAmount?: number;
|
||||
renew?: boolean;
|
||||
};
|
||||
|
||||
export type FeTeamPlanStatusType = {
|
||||
export type FeTeamSubType = {
|
||||
[SubTypeEnum.standard]?: TeamSubSchema;
|
||||
standardConstants?: TeamStandardSubPlanItemType;
|
||||
[SubTypeEnum.extraDatasetSize]?: TeamSubSchema;
|
||||
[SubTypeEnum.extraPoints]?: TeamSubSchema;
|
||||
|
||||
standardMaxDatasetSize: number;
|
||||
totalPoints: number;
|
||||
usedPoints: number;
|
||||
standardMaxDatasetSize?: number;
|
||||
standardMaxPoints?: number;
|
||||
|
||||
// standard + extra
|
||||
standardMaxPoints: number;
|
||||
datasetMaxSize: number;
|
||||
usedDatasetSize: number;
|
||||
};
|
||||
|
26
packages/global/support/wallet/usage/api.d.ts
vendored
@@ -1,26 +0,0 @@
|
||||
import { UsageSourceEnum } from './constants';
|
||||
import { UsageListItemCountType, UsageListItemType } from './type';
|
||||
|
||||
export type CreateTrainingUsageProps = {
|
||||
name: string;
|
||||
datasetId: string;
|
||||
};
|
||||
|
||||
export type ConcatUsageProps = UsageListItemCountType & {
|
||||
teamId: string;
|
||||
tmbId: string;
|
||||
billId?: string;
|
||||
totalPoints: number;
|
||||
listIndex?: number;
|
||||
};
|
||||
|
||||
export type CreateUsageProps = {
|
||||
teamId: string;
|
||||
tmbId: string;
|
||||
appName: string;
|
||||
appId?: string;
|
||||
totalPoints: number;
|
||||
// inputTokens: number;
|
||||
source: `${UsageSourceEnum}`;
|
||||
list: UsageListItemType[];
|
||||
};
|
@@ -1,21 +0,0 @@
|
||||
export enum UsageSourceEnum {
|
||||
fastgpt = 'fastgpt',
|
||||
api = 'api',
|
||||
shareLink = 'shareLink',
|
||||
training = 'training'
|
||||
}
|
||||
|
||||
export const UsageSourceMap = {
|
||||
[UsageSourceEnum.fastgpt]: {
|
||||
label: '在线使用'
|
||||
},
|
||||
[UsageSourceEnum.api]: {
|
||||
label: 'Api'
|
||||
},
|
||||
[UsageSourceEnum.shareLink]: {
|
||||
label: '免登录链接'
|
||||
},
|
||||
[UsageSourceEnum.training]: {
|
||||
label: 'dataset.Training Name'
|
||||
}
|
||||
};
|
@@ -1,23 +0,0 @@
|
||||
/* bill common */
|
||||
import { PRICE_SCALE } from '../constants';
|
||||
import { UsageSourceEnum } from './constants';
|
||||
import { AuthUserTypeEnum } from '../../permission/constant';
|
||||
|
||||
/**
|
||||
* dataset price / PRICE_SCALE = real price
|
||||
*/
|
||||
export const formatStorePrice2Read = (val = 0, multiple = 1) => {
|
||||
return Number(((val / PRICE_SCALE) * multiple).toFixed(10));
|
||||
};
|
||||
|
||||
export const getUsageSourceByAuthType = ({
|
||||
shareId,
|
||||
authType
|
||||
}: {
|
||||
shareId?: string;
|
||||
authType?: `${AuthUserTypeEnum}`;
|
||||
}) => {
|
||||
if (shareId) return UsageSourceEnum.shareLink;
|
||||
if (authType === AuthUserTypeEnum.apikey) return UsageSourceEnum.api;
|
||||
return UsageSourceEnum.fastgpt;
|
||||
};
|
26
packages/global/support/wallet/usage/type.d.ts
vendored
@@ -1,26 +0,0 @@
|
||||
import { CreateUsageProps } from './api';
|
||||
import { UsageSourceEnum } from './constants';
|
||||
|
||||
export type UsageListItemCountType = {
|
||||
charsLength?: number;
|
||||
duration?: number;
|
||||
};
|
||||
export type UsageListItemType = UsageListItemCountType & {
|
||||
moduleName: string;
|
||||
amount: number;
|
||||
model?: string;
|
||||
};
|
||||
|
||||
export type UsageSchemaType = CreateUsageProps & {
|
||||
_id: string;
|
||||
time: Date;
|
||||
};
|
||||
|
||||
export type UsageItemType = {
|
||||
id: string;
|
||||
time: Date;
|
||||
appName: string;
|
||||
source: UsageSchemaType['source'];
|
||||
totalPoints: number;
|
||||
list: UsageSchemaType['list'];
|
||||
};
|
@@ -38,22 +38,22 @@ export const insertDatasetDataVector = async ({
|
||||
};
|
||||
};
|
||||
|
||||
// export const updateDatasetDataVector = async ({
|
||||
// id,
|
||||
// ...props
|
||||
// }: InsertVectorProps & {
|
||||
// id: string;
|
||||
// query: string;
|
||||
// model: VectorModelItemType;
|
||||
// }) => {
|
||||
// // insert new vector
|
||||
// const { charsLength, insertId } = await insertDatasetDataVector(props);
|
||||
export const updateDatasetDataVector = async ({
|
||||
id,
|
||||
...props
|
||||
}: InsertVectorProps & {
|
||||
id: string;
|
||||
query: string;
|
||||
model: VectorModelItemType;
|
||||
}) => {
|
||||
// insert new vector
|
||||
const { charsLength, insertId } = await insertDatasetDataVector(props);
|
||||
|
||||
// // delete old vector
|
||||
// await deleteDatasetDataVector({
|
||||
// teamId: props.teamId,
|
||||
// id
|
||||
// });
|
||||
// delete old vector
|
||||
await deleteDatasetDataVector({
|
||||
teamId: props.teamId,
|
||||
id
|
||||
});
|
||||
|
||||
// return { charsLength, insertId };
|
||||
// };
|
||||
return { charsLength, insertId };
|
||||
};
|
||||
|
@@ -25,18 +25,6 @@ export async function initPg() {
|
||||
await PgClient.query(
|
||||
`CREATE INDEX CONCURRENTLY IF NOT EXISTS vector_index ON ${PgDatasetTableName} USING hnsw (vector vector_ip_ops) WITH (m = 32, ef_construction = 64);`
|
||||
);
|
||||
await PgClient.query(
|
||||
`CREATE INDEX CONCURRENTLY IF NOT EXISTS team_dataset_index ON ${PgDatasetTableName} USING btree(team_id, dataset_id);`
|
||||
);
|
||||
await PgClient.query(
|
||||
` CREATE INDEX CONCURRENTLY IF NOT EXISTS team_collection_index ON ${PgDatasetTableName} USING btree(team_id, collection_id);`
|
||||
);
|
||||
await PgClient.query(
|
||||
`CREATE INDEX CONCURRENTLY IF NOT EXISTS team_id_index ON ${PgDatasetTableName} USING btree(team_id, id);`
|
||||
);
|
||||
await PgClient.query(
|
||||
`CREATE INDEX CONCURRENTLY IF NOT EXISTS create_time_index ON ${PgDatasetTableName} USING btree(createtime);`
|
||||
);
|
||||
|
||||
console.log('init pg successful');
|
||||
} catch (error) {
|
||||
|
@@ -11,7 +11,6 @@ export const getAIApi = (props?: {
|
||||
timeout?: number;
|
||||
}) => {
|
||||
const { userKey, timeout } = props || {};
|
||||
|
||||
return new OpenAI({
|
||||
apiKey: userKey?.key || systemAIChatKey,
|
||||
baseURL: userKey?.baseUrl || baseUrl,
|
||||
|
159
packages/service/core/ai/functions/cfr.ts
Normal file
@@ -0,0 +1,159 @@
|
||||
import { replaceVariable } from '@fastgpt/global/common/string/tools';
|
||||
import { getAIApi } from '../config';
|
||||
import { ChatItemType } from '@fastgpt/global/core/chat/type';
|
||||
|
||||
/*
|
||||
cfr: coreference resolution - 指代消除
|
||||
可以根据上下文,完事当前问题指代内容,利于检索。
|
||||
*/
|
||||
|
||||
const defaultPrompt = `请不要回答任何问题。
|
||||
你的任务是结合历史记录,为当前问题,实现代词替换,确保问题描述的对象清晰明确。例如:
|
||||
历史记录:
|
||||
"""
|
||||
Q: 对话背景。
|
||||
A: 关于 FatGPT 的介绍和使用等问题。
|
||||
"""
|
||||
当前问题: 怎么下载
|
||||
输出: FastGPT 怎么下载?
|
||||
----------------
|
||||
历史记录:
|
||||
"""
|
||||
Q: 报错 "no connection"
|
||||
A: FastGPT 报错"no connection"可能是因为……
|
||||
"""
|
||||
当前问题: 怎么解决
|
||||
输出: FastGPT 报错"no connection"如何解决?
|
||||
----------------
|
||||
历史记录:
|
||||
"""
|
||||
Q: 作者是谁?
|
||||
A: FastGPT 的作者是 labring。
|
||||
"""
|
||||
当前问题: 介绍下他
|
||||
输出: 介绍下 FastGPT 的作者 labring。
|
||||
----------------
|
||||
历史记录:
|
||||
"""
|
||||
Q: 作者是谁?
|
||||
A: FastGPT 的作者是 labring。
|
||||
"""
|
||||
当前问题: 我想购买商业版。
|
||||
输出: FastGPT 商业版如何购买?
|
||||
----------------
|
||||
历史记录:
|
||||
"""
|
||||
Q: 对话背景。
|
||||
A: 关于 FatGPT 的介绍和使用等问题。
|
||||
"""
|
||||
当前问题: nh
|
||||
输出: nh
|
||||
----------------
|
||||
历史记录:
|
||||
"""
|
||||
Q: FastGPT 如何收费?
|
||||
A: FastGPT 收费可以参考……
|
||||
"""
|
||||
当前问题: 你知道 laf 么?
|
||||
输出: 你知道 laf 么?
|
||||
----------------
|
||||
历史记录:
|
||||
"""
|
||||
Q: FastGPT 的优势
|
||||
A: 1. 开源
|
||||
2. 简便
|
||||
3. 扩展性强
|
||||
"""
|
||||
当前问题: 介绍下第2点。
|
||||
输出: 介绍下 FastGPT 简便的优势。
|
||||
----------------
|
||||
历史记录:
|
||||
"""
|
||||
Q: 什么是 FastGPT?
|
||||
A: FastGPT 是一个 RAG 平台。
|
||||
Q: 什么是 Sealos?
|
||||
A: Sealos 是一个云操作系统。
|
||||
"""
|
||||
当前问题: 它们有什么关系?
|
||||
输出: FastGPT 和 Sealos 有什么关系?
|
||||
----------------
|
||||
历史记录:
|
||||
"""
|
||||
{{histories}}
|
||||
"""
|
||||
当前问题: {{query}}
|
||||
输出: `;
|
||||
|
||||
export const queryCfr = async ({
|
||||
chatBg,
|
||||
query,
|
||||
histories = [],
|
||||
model
|
||||
}: {
|
||||
chatBg?: string;
|
||||
query: string;
|
||||
histories: ChatItemType[];
|
||||
model: string;
|
||||
}) => {
|
||||
if (histories.length === 0 && !chatBg) {
|
||||
return {
|
||||
rawQuery: query,
|
||||
cfrQuery: query,
|
||||
model,
|
||||
inputTokens: 0,
|
||||
outputTokens: 0
|
||||
};
|
||||
}
|
||||
|
||||
const systemFewShot = chatBg
|
||||
? `Q: 对话背景。
|
||||
A: ${chatBg}
|
||||
`
|
||||
: '';
|
||||
const historyFewShot = histories
|
||||
.map((item) => {
|
||||
const role = item.obj === 'Human' ? 'Q' : 'A';
|
||||
return `${role}: ${item.value}`;
|
||||
})
|
||||
.join('\n');
|
||||
const concatFewShot = `${systemFewShot}${historyFewShot}`.trim();
|
||||
|
||||
const ai = getAIApi({
|
||||
timeout: 480000
|
||||
});
|
||||
|
||||
const result = await ai.chat.completions.create({
|
||||
model: model,
|
||||
temperature: 0.01,
|
||||
max_tokens: 150,
|
||||
messages: [
|
||||
{
|
||||
role: 'user',
|
||||
content: replaceVariable(defaultPrompt, {
|
||||
query: `${query}`,
|
||||
histories: concatFewShot
|
||||
})
|
||||
}
|
||||
],
|
||||
stream: false
|
||||
});
|
||||
|
||||
const answer = result.choices?.[0]?.message?.content || '';
|
||||
if (!answer) {
|
||||
return {
|
||||
rawQuery: query,
|
||||
cfrQuery: query,
|
||||
model,
|
||||
inputTokens: 0,
|
||||
outputTokens: 0
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
rawQuery: query,
|
||||
cfrQuery: answer,
|
||||
model,
|
||||
inputTokens: result.usage?.prompt_tokens || 0,
|
||||
outputTokens: result.usage?.completion_tokens || 0
|
||||
};
|
||||
};
|
@@ -1,6 +1,5 @@
|
||||
import type { ChatMessageItemType } from '@fastgpt/global/core/ai/type.d';
|
||||
import { getAIApi } from '../config';
|
||||
import { countGptMessagesChars } from '../../chat/utils';
|
||||
|
||||
export const Prompt_QuestionGuide = `我不太清楚问你什么问题,请帮我生成 3 个问题,引导我继续提问。问题的长度应小于20个字符,按 JSON 格式返回: ["问题1", "问题2", "问题3"]`;
|
||||
|
||||
@@ -11,13 +10,6 @@ export async function createQuestionGuide({
|
||||
messages: ChatMessageItemType[];
|
||||
model: string;
|
||||
}) {
|
||||
const concatMessages: ChatMessageItemType[] = [
|
||||
...messages,
|
||||
{
|
||||
role: 'user',
|
||||
content: Prompt_QuestionGuide
|
||||
}
|
||||
];
|
||||
const ai = getAIApi({
|
||||
timeout: 480000
|
||||
});
|
||||
@@ -25,21 +17,28 @@ export async function createQuestionGuide({
|
||||
model: model,
|
||||
temperature: 0.1,
|
||||
max_tokens: 200,
|
||||
messages: concatMessages,
|
||||
messages: [
|
||||
...messages,
|
||||
{
|
||||
role: 'user',
|
||||
content: Prompt_QuestionGuide
|
||||
}
|
||||
],
|
||||
stream: false
|
||||
});
|
||||
|
||||
const answer = data.choices?.[0]?.message?.content || '';
|
||||
const inputTokens = data.usage?.prompt_tokens || 0;
|
||||
const outputTokens = data.usage?.completion_tokens || 0;
|
||||
|
||||
const start = answer.indexOf('[');
|
||||
const end = answer.lastIndexOf(']');
|
||||
|
||||
const charsLength = countGptMessagesChars(concatMessages);
|
||||
|
||||
if (start === -1 || end === -1) {
|
||||
return {
|
||||
result: [],
|
||||
charsLength: 0
|
||||
inputTokens,
|
||||
outputTokens
|
||||
};
|
||||
}
|
||||
|
||||
@@ -51,12 +50,14 @@ export async function createQuestionGuide({
|
||||
try {
|
||||
return {
|
||||
result: JSON.parse(jsonStr),
|
||||
charsLength
|
||||
inputTokens,
|
||||
outputTokens
|
||||
};
|
||||
} catch (error) {
|
||||
return {
|
||||
result: [],
|
||||
charsLength: 0
|
||||
inputTokens,
|
||||
outputTokens
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@@ -1,19 +1,18 @@
|
||||
import { replaceVariable } from '@fastgpt/global/common/string/tools';
|
||||
import { getAIApi } from '../config';
|
||||
import { ChatItemType } from '@fastgpt/global/core/chat/type';
|
||||
import { countGptMessagesChars } from '../../chat/utils';
|
||||
|
||||
/*
|
||||
query extension - 问题扩展
|
||||
可以根据上下文,消除指代性问题以及扩展问题,利于检索。
|
||||
*/
|
||||
|
||||
const defaultPrompt = `作为一个向量检索助手,你的任务是结合历史记录,从不同角度,为“原问题”生成个不同版本的“检索词”,从而提高向量检索的语义丰富度,提高向量检索的精度。生成的问题要求指向对象清晰明确,并与原问题语言相同。例如:
|
||||
const defaultPrompt = `作为一个向量检索助手,你的任务是结合历史记录,从不同角度,为“原问题”生成个不同版本的“检索词”,从而提高向量检索的语义丰富度,提高向量检索的精度。生成的问题要求指向对象清晰明确。例如:
|
||||
历史记录:
|
||||
"""
|
||||
"""
|
||||
原问题: 介绍下剧情。
|
||||
检索词: ["介绍下故事的背景和主要人物。","故事的主题是什么?","剧情是是如何发展的?"]
|
||||
检索词: ["发生了什么故事?","故事梗概是什么?","讲述了什么故事?"]
|
||||
----------------
|
||||
历史记录:
|
||||
"""
|
||||
@@ -21,7 +20,7 @@ Q: 对话背景。
|
||||
A: 当前对话是关于 FatGPT 的介绍和使用等。
|
||||
"""
|
||||
原问题: 怎么下载
|
||||
检索词: ["FastGPT 如何下载?","下载 FastGPT 需要什么条件?","有哪些渠道可以下载 FastGPT?"]
|
||||
检索词: ["FastGPT 怎么下载?","下载 FastGPT 需要什么条件?","有哪些渠道可以下载 FastGPT?"]
|
||||
----------------
|
||||
历史记录:
|
||||
"""
|
||||
@@ -31,15 +30,15 @@ Q: 报错 "no connection"
|
||||
A: 报错"no connection"可能是因为……
|
||||
"""
|
||||
原问题: 怎么解决
|
||||
检索词: ["FastGPT 报错"no connection"如何解决?", "造成 'no connection' 报错的原因。", "FastGPT提示'no connection',要怎么办?"]
|
||||
检索词: ["FastGPT 报错"no connection"如何解决?", "报错 'no connection' 是什么原因?", "FastGPT提示'no connection',要怎么办?"]
|
||||
----------------
|
||||
历史记录:
|
||||
"""
|
||||
Q: 作者是谁?
|
||||
A: FastGPT 的作者是 labring。
|
||||
"""
|
||||
原问题: Tell me about him
|
||||
检索词: ["Introduce labring, the author of FastGPT." ," Background information on author labring." "," Why does labring do FastGPT?"]
|
||||
原问题: 介绍下他
|
||||
检索词: ["介绍下 FastGPT 的作者 labring。","作者 labring 的背景信息。","labring 为什么要做 FastGPT?"]
|
||||
----------------
|
||||
历史记录:
|
||||
"""
|
||||
@@ -106,7 +105,8 @@ export const queryExtension = async ({
|
||||
rawQuery: string;
|
||||
extensionQueries: string[];
|
||||
model: string;
|
||||
charsLength: number;
|
||||
inputTokens: number;
|
||||
outputTokens: number;
|
||||
}> => {
|
||||
const systemFewShot = chatBg
|
||||
? `Q: 对话背景。
|
||||
@@ -125,20 +125,18 @@ A: ${chatBg}
|
||||
timeout: 480000
|
||||
});
|
||||
|
||||
const messages = [
|
||||
{
|
||||
role: 'user',
|
||||
content: replaceVariable(defaultPrompt, {
|
||||
query: `${query}`,
|
||||
histories: concatFewShot
|
||||
})
|
||||
}
|
||||
];
|
||||
const result = await ai.chat.completions.create({
|
||||
model: model,
|
||||
temperature: 0.01,
|
||||
// @ts-ignore
|
||||
messages,
|
||||
messages: [
|
||||
{
|
||||
role: 'user',
|
||||
content: replaceVariable(defaultPrompt, {
|
||||
query: `${query}`,
|
||||
histories: concatFewShot
|
||||
})
|
||||
}
|
||||
],
|
||||
stream: false
|
||||
});
|
||||
|
||||
@@ -148,7 +146,8 @@ A: ${chatBg}
|
||||
rawQuery: query,
|
||||
extensionQueries: [],
|
||||
model,
|
||||
charsLength: 0
|
||||
inputTokens: 0,
|
||||
outputTokens: 0
|
||||
};
|
||||
}
|
||||
|
||||
@@ -161,7 +160,8 @@ A: ${chatBg}
|
||||
rawQuery: query,
|
||||
extensionQueries: queries,
|
||||
model,
|
||||
charsLength: countGptMessagesChars(messages)
|
||||
inputTokens: result.usage?.prompt_tokens || 0,
|
||||
outputTokens: result.usage?.completion_tokens || 0
|
||||
};
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
@@ -169,7 +169,8 @@ A: ${chatBg}
|
||||
rawQuery: query,
|
||||
extensionQueries: [],
|
||||
model,
|
||||
charsLength: 0
|
||||
inputTokens: 0,
|
||||
outputTokens: 0
|
||||
};
|
||||
}
|
||||
};
|
||||
|
@@ -61,9 +61,6 @@ const AppSchema = new Schema({
|
||||
type: String,
|
||||
enum: Object.keys(PermissionTypeMap),
|
||||
default: PermissionTypeEnum.private
|
||||
},
|
||||
teamTags: {
|
||||
type: [String]
|
||||
}
|
||||
});
|
||||
|
||||
|
@@ -92,8 +92,6 @@ try {
|
||||
ChatItemSchema.index({ appId: 1, chatId: 1, dataId: 1 }, { background: true });
|
||||
// admin charts
|
||||
ChatItemSchema.index({ time: -1, obj: 1 }, { background: true });
|
||||
// timer, clear history
|
||||
ChatItemSchema.index({ teamId: 1, time: -1 }, { background: true });
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
|
@@ -83,9 +83,6 @@ try {
|
||||
ChatSchema.index({ teamId: 1, appId: 1, updateTime: -1 }, { background: true });
|
||||
// get share chat history
|
||||
ChatSchema.index({ shareId: 1, outLinkUid: 1, updateTime: -1, source: 1 }, { background: true });
|
||||
|
||||
// timer, clear history
|
||||
ChatSchema.index({ teamId: 1, updateTime: -1 }, { background: true });
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
|
@@ -2,10 +2,7 @@ import type { ChatItemType } from '@fastgpt/global/core/chat/type.d';
|
||||
import { ChatRoleEnum, IMG_BLOCK_KEY } from '@fastgpt/global/core/chat/constants';
|
||||
import { countMessagesTokens, countPromptTokens } from '@fastgpt/global/common/string/tiktoken';
|
||||
import { adaptRole_Chat2Message } from '@fastgpt/global/core/chat/adapt';
|
||||
import type {
|
||||
ChatCompletionContentPart,
|
||||
ChatMessageItemType
|
||||
} from '@fastgpt/global/core/ai/type.d';
|
||||
import type { ChatCompletionContentPart } from '@fastgpt/global/core/ai/type.d';
|
||||
import axios from 'axios';
|
||||
|
||||
/* slice chat context by tokens */
|
||||
@@ -59,12 +56,6 @@ export function ChatContextFilter({
|
||||
return [...systemPrompts, ...chats];
|
||||
}
|
||||
|
||||
export const countMessagesChars = (messages: ChatItemType[]) => {
|
||||
return messages.reduce((sum, item) => sum + item.value.length, 0);
|
||||
};
|
||||
export const countGptMessagesChars = (messages: ChatMessageItemType[]) =>
|
||||
messages.reduce((sum, item) => sum + item.content.length, 0);
|
||||
|
||||
/**
|
||||
string to vision model. Follow the markdown code block rule for interception:
|
||||
|
||||
|
@@ -147,6 +147,8 @@ export async function delCollectionAndRelatedSources({
|
||||
collectionId: { $in: collectionIds }
|
||||
});
|
||||
|
||||
await delay(2000);
|
||||
|
||||
// delete dataset.datas
|
||||
await MongoDatasetData.deleteMany({ teamId, collectionId: { $in: collectionIds } }, { session });
|
||||
// delete imgs
|
||||
|
@@ -66,11 +66,6 @@ export async function delDatasetRelevantData({
|
||||
if (!datasets.length) return;
|
||||
|
||||
const teamId = datasets[0].teamId;
|
||||
|
||||
if (!teamId) {
|
||||
return Promise.reject('teamId is required');
|
||||
}
|
||||
|
||||
const datasetIds = datasets.map((item) => String(item._id));
|
||||
|
||||
// Get _id, teamId, fileId, metadata.relatedImgId for all collections
|
||||
|
@@ -7,6 +7,10 @@ import {
|
||||
} from '@fastgpt/global/support/user/team/constant';
|
||||
import { DatasetCollectionName } from '../schema';
|
||||
import { DatasetColCollectionName } from '../collection/schema';
|
||||
import {
|
||||
DatasetDataIndexTypeEnum,
|
||||
DatasetDataIndexTypeMap
|
||||
} from '@fastgpt/global/core/dataset/constants';
|
||||
|
||||
export const DatasetDataCollectionName = 'dataset.datas';
|
||||
|
||||
@@ -50,6 +54,11 @@ const DatasetDataSchema = new Schema({
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
type: {
|
||||
type: String,
|
||||
enum: Object.keys(DatasetDataIndexTypeMap),
|
||||
default: DatasetDataIndexTypeEnum.custom
|
||||
},
|
||||
dataId: {
|
||||
type: String,
|
||||
required: true
|
||||
|
@@ -14,54 +14,22 @@ export const datasetSearchQueryExtension = async ({
|
||||
extensionBg?: string;
|
||||
histories?: ChatItemType[];
|
||||
}) => {
|
||||
const filterSamQuery = (queries: string[]) => {
|
||||
const set = new Set<string>();
|
||||
const filterSameQueries = queries.filter((item) => {
|
||||
// 删除所有的标点符号与空格等,只对文本进行比较
|
||||
const str = hashStr(item.replace(/[^\p{L}\p{N}]/gu, ''));
|
||||
if (set.has(str)) return false;
|
||||
set.add(str);
|
||||
return true;
|
||||
});
|
||||
|
||||
return filterSameQueries;
|
||||
};
|
||||
|
||||
let { queries, rewriteQuery, alreadyExtension } = (() => {
|
||||
// concat query
|
||||
let rewriteQuery =
|
||||
histories.length > 0
|
||||
? `${histories
|
||||
.map((item) => {
|
||||
return `${item.obj}: ${item.value}`;
|
||||
})
|
||||
.join('\n')}
|
||||
Human: ${query}
|
||||
`
|
||||
: query;
|
||||
|
||||
/* if query already extension, direct parse */
|
||||
try {
|
||||
const jsonParse = JSON.parse(query);
|
||||
const queries: string[] = Array.isArray(jsonParse) ? filterSamQuery(jsonParse) : [query];
|
||||
const alreadyExtension = Array.isArray(jsonParse);
|
||||
return {
|
||||
queries,
|
||||
rewriteQuery: alreadyExtension ? queries.join('\n') : rewriteQuery,
|
||||
alreadyExtension: alreadyExtension
|
||||
};
|
||||
} catch (error) {
|
||||
return {
|
||||
queries: [query],
|
||||
rewriteQuery,
|
||||
alreadyExtension: false
|
||||
};
|
||||
}
|
||||
})();
|
||||
// concat query
|
||||
let queries = [query];
|
||||
let rewriteQuery =
|
||||
histories.length > 0
|
||||
? `${histories
|
||||
.map((item) => {
|
||||
return `${item.obj}: ${item.value}`;
|
||||
})
|
||||
.join('\n')}
|
||||
Human: ${query}
|
||||
`
|
||||
: query;
|
||||
|
||||
// ai extension
|
||||
const aiExtensionResult = await (async () => {
|
||||
if (!extensionModel || alreadyExtension) return;
|
||||
if (!extensionModel) return;
|
||||
const result = await queryExtension({
|
||||
chatBg: extensionBg,
|
||||
query,
|
||||
@@ -71,13 +39,23 @@ export const datasetSearchQueryExtension = async ({
|
||||
if (result.extensionQueries?.length === 0) return;
|
||||
return result;
|
||||
})();
|
||||
|
||||
if (aiExtensionResult) {
|
||||
queries = filterSamQuery(queries.concat(aiExtensionResult.extensionQueries));
|
||||
queries = queries.concat(aiExtensionResult.extensionQueries);
|
||||
rewriteQuery = queries.join('\n');
|
||||
}
|
||||
|
||||
const set = new Set<string>();
|
||||
const filterSameQueries = queries.filter((item) => {
|
||||
// 删除所有的标点符号与空格等,只对文本进行比较
|
||||
const str = hashStr(item.replace(/[^\p{L}\p{N}]/gu, ''));
|
||||
if (set.has(str)) return false;
|
||||
set.add(str);
|
||||
return true;
|
||||
});
|
||||
|
||||
return {
|
||||
concatQueries: queries,
|
||||
concatQueries: filterSameQueries,
|
||||
rewriteQuery,
|
||||
aiExtensionResult
|
||||
};
|
||||
|
@@ -57,7 +57,7 @@ export async function pushDataListToTrainingQueue({
|
||||
if (trainingMode === TrainingModeEnum.chunk) {
|
||||
const vectorModelData = vectorModelList?.find((item) => item.model === vectorModel);
|
||||
if (!vectorModelData) {
|
||||
return Promise.reject(`File model ${vectorModel} is inValid`);
|
||||
return Promise.reject(`Model ${vectorModel} is inValid`);
|
||||
}
|
||||
|
||||
return {
|
||||
@@ -70,7 +70,7 @@ export async function pushDataListToTrainingQueue({
|
||||
if (trainingMode === TrainingModeEnum.qa) {
|
||||
const qaModelData = datasetModelList?.find((item) => item.model === agentModel);
|
||||
if (!qaModelData) {
|
||||
return Promise.reject(`Vector model ${agentModel} is inValid`);
|
||||
return Promise.reject(`Model ${agentModel} is inValid`);
|
||||
}
|
||||
return {
|
||||
maxToken: qaModelData.maxContext * 0.8,
|
||||
|
@@ -2,7 +2,7 @@
|
||||
import { connectionMongo, type Model } from '../../../common/mongo';
|
||||
const { Schema, model, models } = connectionMongo;
|
||||
import { DatasetTrainingSchemaType } from '@fastgpt/global/core/dataset/type';
|
||||
import { TrainingTypeMap } from '@fastgpt/global/core/dataset/constants';
|
||||
import { DatasetDataIndexTypeMap, TrainingTypeMap } from '@fastgpt/global/core/dataset/constants';
|
||||
import { DatasetColCollectionName } from '../collection/schema';
|
||||
import { DatasetCollectionName } from '../schema';
|
||||
import {
|
||||
@@ -86,6 +86,11 @@ const TrainingDataSchema = new Schema({
|
||||
indexes: {
|
||||
type: [
|
||||
{
|
||||
type: {
|
||||
type: String,
|
||||
enum: Object.keys(DatasetDataIndexTypeMap),
|
||||
required: true
|
||||
},
|
||||
text: {
|
||||
type: String,
|
||||
required: true
|
||||
|
@@ -15,7 +15,7 @@
|
||||
"nextjs-cors": "^2.1.2",
|
||||
"node-cron": "^3.0.3",
|
||||
"pg": "^8.10.0",
|
||||
"date-fns": "2.30.0",
|
||||
"date-fns": "^2.30.0",
|
||||
"tunnel": "^0.0.6"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
@@ -19,15 +19,14 @@ export async function authOpenApiKey({ apikey }: { apikey: string }) {
|
||||
// auth limit
|
||||
// @ts-ignore
|
||||
if (global.feConfigs?.isPlus) {
|
||||
await POST('/support/openapi/authLimit', {
|
||||
openApi: openApi.toObject()
|
||||
} as AuthOpenApiLimitProps);
|
||||
await POST('/support/openapi/authLimit', { openApi } as AuthOpenApiLimitProps);
|
||||
}
|
||||
|
||||
updateApiKeyUsedTime(openApi._id);
|
||||
|
||||
return {
|
||||
apikey,
|
||||
userId: String(openApi.userId),
|
||||
teamId: String(openApi.teamId),
|
||||
tmbId: String(openApi.tmbId),
|
||||
appId: openApi.appId || ''
|
||||
|
@@ -1,6 +1,8 @@
|
||||
import { connectionMongo, type Model } from '../../common/mongo';
|
||||
const { Schema, model, models } = connectionMongo;
|
||||
import type { OpenApiSchema } from '@fastgpt/global/support/openapi/type';
|
||||
import { PRICE_SCALE } from '@fastgpt/global/support/wallet/bill/constants';
|
||||
import { formatStorePrice2Read } from '@fastgpt/global/support/wallet/bill/tools';
|
||||
import {
|
||||
TeamCollectionName,
|
||||
TeamMemberCollectionName
|
||||
@@ -8,6 +10,10 @@ import {
|
||||
|
||||
const OpenApiSchema = new Schema(
|
||||
{
|
||||
userId: {
|
||||
type: Schema.Types.ObjectId,
|
||||
ref: 'user'
|
||||
},
|
||||
teamId: {
|
||||
type: Schema.Types.ObjectId,
|
||||
ref: TeamCollectionName,
|
||||
@@ -38,17 +44,22 @@ const OpenApiSchema = new Schema(
|
||||
type: String,
|
||||
default: 'Api Key'
|
||||
},
|
||||
usagePoints: {
|
||||
usage: {
|
||||
// total usage. value from bill total
|
||||
type: Number,
|
||||
default: 0
|
||||
default: 0,
|
||||
get: (val: number) => formatStorePrice2Read(val)
|
||||
},
|
||||
limit: {
|
||||
expiredTime: {
|
||||
type: Date
|
||||
},
|
||||
maxUsagePoints: {
|
||||
credit: {
|
||||
// value from user settings
|
||||
type: Number,
|
||||
default: -1
|
||||
default: -1,
|
||||
set: (val: number) => val * PRICE_SCALE,
|
||||
get: (val: number) => formatStorePrice2Read(val)
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@@ -8,21 +8,15 @@ export function updateApiKeyUsedTime(id: string) {
|
||||
});
|
||||
}
|
||||
|
||||
export function updateApiKeyUsage({
|
||||
apikey,
|
||||
totalPoints
|
||||
}: {
|
||||
apikey: string;
|
||||
totalPoints: number;
|
||||
}) {
|
||||
export function updateApiKeyUsage({ apikey, usage }: { apikey: string; usage: number }) {
|
||||
MongoOpenApi.findOneAndUpdate(
|
||||
{ apiKey: apikey },
|
||||
{
|
||||
$inc: {
|
||||
usagePoints: totalPoints
|
||||
usage
|
||||
}
|
||||
}
|
||||
).catch((err) => {
|
||||
console.log('update apiKey totalPoints error', err);
|
||||
console.log('update apiKey usage error', err);
|
||||
});
|
||||
}
|
||||
|
@@ -35,7 +35,8 @@ const OutLinkSchema = new Schema({
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
usagePoints: {
|
||||
total: {
|
||||
// total amount
|
||||
type: Number,
|
||||
default: 0
|
||||
},
|
||||
@@ -47,10 +48,6 @@ const OutLinkSchema = new Schema({
|
||||
default: false
|
||||
},
|
||||
limit: {
|
||||
maxUsagePoints: {
|
||||
type: Number,
|
||||
default: -1
|
||||
},
|
||||
expiredTime: {
|
||||
type: Date
|
||||
},
|
||||
@@ -58,18 +55,16 @@ const OutLinkSchema = new Schema({
|
||||
type: Number,
|
||||
default: 1000
|
||||
},
|
||||
credit: {
|
||||
type: Number,
|
||||
default: -1
|
||||
},
|
||||
hookUrl: {
|
||||
type: String
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
try {
|
||||
OutLinkSchema.index({ shareId: -1 });
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
|
||||
export const MongoOutLink: Model<SchemaType> =
|
||||
models['outlinks'] || model('outlinks', OutLinkSchema);
|
||||
|
||||
|
@@ -1,19 +1,18 @@
|
||||
import axios from 'axios';
|
||||
import { MongoOutLink } from './schema';
|
||||
import { FastGPTProUrl } from '../../common/system/constants';
|
||||
import { ChatHistoryItemResType } from '@fastgpt/global/core/chat/type';
|
||||
|
||||
export const addOutLinkUsage = async ({
|
||||
export const updateOutLinkUsage = async ({
|
||||
shareId,
|
||||
totalPoints
|
||||
total
|
||||
}: {
|
||||
shareId: string;
|
||||
totalPoints: number;
|
||||
total: number;
|
||||
}) => {
|
||||
MongoOutLink.findOneAndUpdate(
|
||||
{ shareId },
|
||||
{
|
||||
$inc: { usagePoints: totalPoints },
|
||||
$inc: { total },
|
||||
lastTime: new Date()
|
||||
}
|
||||
).catch((err) => {
|
||||
@@ -24,13 +23,11 @@ export const addOutLinkUsage = async ({
|
||||
export const pushResult2Remote = async ({
|
||||
outLinkUid,
|
||||
shareId,
|
||||
appName,
|
||||
responseData
|
||||
}: {
|
||||
outLinkUid?: string; // raw id, not parse
|
||||
shareId?: string;
|
||||
appName: string;
|
||||
responseData?: ChatHistoryItemResType[];
|
||||
responseData?: any[];
|
||||
}) => {
|
||||
if (!shareId || !outLinkUid || !FastGPTProUrl) return;
|
||||
try {
|
||||
@@ -45,7 +42,6 @@ export const pushResult2Remote = async ({
|
||||
url: '/shareAuth/finish',
|
||||
data: {
|
||||
token: outLinkUid,
|
||||
appName,
|
||||
responseData
|
||||
}
|
||||
});
|
||||
|
@@ -107,7 +107,7 @@ export async function authDatasetCollection({
|
||||
collection: CollectionWithDatasetType;
|
||||
}
|
||||
> {
|
||||
const { teamId, tmbId } = await parseHeaderCert(props);
|
||||
const { userId, teamId, tmbId } = await parseHeaderCert(props);
|
||||
const { role } = await getTmbInfoByTmbId({ tmbId });
|
||||
|
||||
const { collection, isOwner, canWrite } = await (async () => {
|
||||
@@ -143,6 +143,7 @@ export async function authDatasetCollection({
|
||||
})();
|
||||
|
||||
return {
|
||||
userId,
|
||||
teamId,
|
||||
tmbId,
|
||||
collection,
|
||||
@@ -162,7 +163,7 @@ export async function authDatasetFile({
|
||||
file: DatasetFileSchema;
|
||||
}
|
||||
> {
|
||||
const { teamId, tmbId } = await parseHeaderCert(props);
|
||||
const { userId, teamId, tmbId } = await parseHeaderCert(props);
|
||||
|
||||
const [file, collection] = await Promise.all([
|
||||
getFileById({ bucketName: BucketNameEnum.dataset, fileId }),
|
||||
@@ -189,6 +190,7 @@ export async function authDatasetFile({
|
||||
});
|
||||
|
||||
return {
|
||||
userId,
|
||||
teamId,
|
||||
tmbId,
|
||||
file,
|
||||
|
@@ -12,7 +12,7 @@ export async function authUserNotVisitor(props: AuthModeType): Promise<
|
||||
role: `${TeamMemberRoleEnum}`;
|
||||
}
|
||||
> {
|
||||
const { teamId, tmbId } = await parseHeaderCert(props);
|
||||
const { userId, teamId, tmbId } = await parseHeaderCert(props);
|
||||
const team = await getTmbInfoByTmbId({ tmbId });
|
||||
|
||||
if (team.role === TeamMemberRoleEnum.visitor) {
|
||||
@@ -20,6 +20,7 @@ export async function authUserNotVisitor(props: AuthModeType): Promise<
|
||||
}
|
||||
|
||||
return {
|
||||
userId,
|
||||
teamId,
|
||||
tmbId,
|
||||
team,
|
||||
|
@@ -94,10 +94,10 @@ export async function parseHeaderCert({
|
||||
})();
|
||||
|
||||
// auth apikey
|
||||
const { teamId, tmbId, appId: apiKeyAppId = '' } = await authOpenApiKey({ apikey });
|
||||
const { userId, teamId, tmbId, appId: apiKeyAppId = '' } = await authOpenApiKey({ apikey });
|
||||
|
||||
return {
|
||||
uid: '',
|
||||
uid: userId,
|
||||
teamId,
|
||||
tmbId,
|
||||
apikey,
|
||||
|
23
packages/service/support/permission/limit/dataset.ts
Normal file
@@ -0,0 +1,23 @@
|
||||
import { StandSubPlanLevelMapType } from '@fastgpt/global/support/wallet/sub/type';
|
||||
import { getVectorCountByTeamId } from '../../../common/vectorStore/controller';
|
||||
import { getTeamDatasetMaxSize } from '../../wallet/sub/utils';
|
||||
|
||||
export const checkDatasetLimit = async ({
|
||||
teamId,
|
||||
insertLen = 0,
|
||||
standardPlans
|
||||
}: {
|
||||
teamId: string;
|
||||
insertLen?: number;
|
||||
standardPlans?: StandSubPlanLevelMapType;
|
||||
}) => {
|
||||
const [{ maxSize }, usedSize] = await Promise.all([
|
||||
getTeamDatasetMaxSize({ teamId, standardPlans }),
|
||||
getVectorCountByTeamId(teamId)
|
||||
]);
|
||||
|
||||
if (usedSize + insertLen >= maxSize) {
|
||||
return Promise.reject(`数据库容量不足,无法继续添加。可以在账号页面进行扩容。`);
|
||||
}
|
||||
return;
|
||||
};
|
@@ -2,6 +2,7 @@ import { UserType } from '@fastgpt/global/support/user/type';
|
||||
import { MongoUser } from './schema';
|
||||
import { getTmbInfoByTmbId, getUserDefaultTeam } from './team/controller';
|
||||
import { ERROR_ENUM } from '@fastgpt/global/common/error/errorCode';
|
||||
import { UserErrEnum } from '@fastgpt/global/common/error/code/user';
|
||||
|
||||
export async function authUserExist({ userId, username }: { userId?: string; username?: string }) {
|
||||
if (userId) {
|
||||
@@ -46,3 +47,22 @@ export async function getUserDetail({
|
||||
team: tmb
|
||||
};
|
||||
}
|
||||
|
||||
export async function getUserAndAuthBalance({
|
||||
tmbId,
|
||||
minBalance
|
||||
}: {
|
||||
tmbId: string;
|
||||
minBalance?: number;
|
||||
}) {
|
||||
const user = await getUserDetail({ tmbId });
|
||||
|
||||
if (!user) {
|
||||
return Promise.reject(UserErrEnum.unAuthUser);
|
||||
}
|
||||
if (minBalance !== undefined && user.team.balance < minBalance) {
|
||||
return Promise.reject(UserErrEnum.balanceNotEnough);
|
||||
}
|
||||
|
||||
return user;
|
||||
}
|
||||
|
@@ -1,7 +1,7 @@
|
||||
import { connectionMongo, type Model } from '../../common/mongo';
|
||||
const { Schema, model, models } = connectionMongo;
|
||||
import { hashStr } from '@fastgpt/global/common/string/tools';
|
||||
import { PRICE_SCALE } from '@fastgpt/global/support/wallet/constants';
|
||||
import { PRICE_SCALE } from '@fastgpt/global/support/wallet/bill/constants';
|
||||
import type { UserModelSchema } from '@fastgpt/global/support/user/type';
|
||||
import { UserStatusEnum, userStatusMap } from '@fastgpt/global/support/user/constant';
|
||||
|
||||
@@ -63,8 +63,6 @@ const UserSchema = new Schema({
|
||||
});
|
||||
|
||||
try {
|
||||
// login
|
||||
UserSchema.index({ username: 1, password: 1 });
|
||||
UserSchema.index({ createTime: -1 });
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
|
@@ -36,7 +36,7 @@ export async function getTmbInfoByTmbId({ tmbId }: { tmbId: string }) {
|
||||
return Promise.reject('tmbId or userId is required');
|
||||
}
|
||||
return getTeamMember({
|
||||
_id: new Types.ObjectId(String(tmbId)),
|
||||
_id: new Types.ObjectId(tmbId),
|
||||
status: notLeaveStatus
|
||||
});
|
||||
}
|
||||
|
@@ -27,10 +27,7 @@ const TeamSchema = new Schema({
|
||||
},
|
||||
maxSize: {
|
||||
type: Number,
|
||||
default: 1
|
||||
},
|
||||
tagsUrl: {
|
||||
type: String
|
||||
default: 3
|
||||
},
|
||||
limit: {
|
||||
lastExportDatasetTime: {
|
||||
|
@@ -1,35 +0,0 @@
|
||||
import { connectionMongo, type Model } from '../../../common/mongo';
|
||||
const { Schema, model, models } = connectionMongo;
|
||||
import { TeamTagsSchema as TeamTagsSchemaType } from '@fastgpt/global/support/user/team/type.d';
|
||||
import {
|
||||
TeamCollectionName,
|
||||
TeamTagsCollectionName
|
||||
} from '@fastgpt/global/support/user/team/constant';
|
||||
|
||||
const TeamTagsSchema = new Schema({
|
||||
label: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
teamId: {
|
||||
type: Schema.Types.ObjectId,
|
||||
ref: TeamCollectionName,
|
||||
required: true
|
||||
},
|
||||
key: {
|
||||
type: String
|
||||
},
|
||||
createTime: {
|
||||
type: Date,
|
||||
default: () => new Date()
|
||||
}
|
||||
});
|
||||
|
||||
try {
|
||||
TeamTagsSchema.index({ teamId: 1 });
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
|
||||
export const MongoTeamTags: Model<TeamTagsSchemaType> =
|
||||
models[TeamTagsCollectionName] || model(TeamTagsCollectionName, TeamTagsSchema);
|
@@ -1,8 +1,8 @@
|
||||
import { UsageSourceEnum } from '@fastgpt/global/support/wallet/usage/constants';
|
||||
import { MongoUsage } from './schema';
|
||||
import { BillSourceEnum } from '@fastgpt/global/support/wallet/bill/constants';
|
||||
import { MongoBill } from './schema';
|
||||
import { ClientSession } from '../../../common/mongo';
|
||||
|
||||
export const createTrainingUsage = async ({
|
||||
export const createTrainingBill = async ({
|
||||
teamId,
|
||||
tmbId,
|
||||
appName,
|
||||
@@ -14,33 +14,33 @@ export const createTrainingUsage = async ({
|
||||
teamId: string;
|
||||
tmbId: string;
|
||||
appName: string;
|
||||
billSource: `${UsageSourceEnum}`;
|
||||
billSource: `${BillSourceEnum}`;
|
||||
vectorModel: string;
|
||||
agentModel: string;
|
||||
session?: ClientSession;
|
||||
}) => {
|
||||
const [{ _id }] = await MongoUsage.create(
|
||||
const [{ _id }] = await MongoBill.create(
|
||||
[
|
||||
{
|
||||
teamId,
|
||||
tmbId,
|
||||
appName,
|
||||
source: billSource,
|
||||
totalPoints: 0,
|
||||
list: [
|
||||
{
|
||||
moduleName: 'support.wallet.moduleName.index',
|
||||
moduleName: 'wallet.moduleName.index',
|
||||
model: vectorModel,
|
||||
charsLength: 0,
|
||||
amount: 0
|
||||
},
|
||||
{
|
||||
moduleName: 'support.wallet.moduleName.qa',
|
||||
moduleName: 'wallet.moduleName.qa',
|
||||
model: agentModel,
|
||||
charsLength: 0,
|
||||
amount: 0
|
||||
}
|
||||
]
|
||||
],
|
||||
total: 0
|
||||
}
|
||||
],
|
||||
{ session }
|
@@ -1,15 +1,13 @@
|
||||
import { connectionMongo, type Model } from '../../../common/mongo';
|
||||
const { Schema, model, models } = connectionMongo;
|
||||
import { UsageSchemaType } from '@fastgpt/global/support/wallet/usage/type';
|
||||
import { UsageSourceMap } from '@fastgpt/global/support/wallet/usage/constants';
|
||||
import { BillSchema as BillType } from '@fastgpt/global/support/wallet/bill/type';
|
||||
import { BillSourceMap } from '@fastgpt/global/support/wallet/bill/constants';
|
||||
import {
|
||||
TeamCollectionName,
|
||||
TeamMemberCollectionName
|
||||
} from '@fastgpt/global/support/user/team/constant';
|
||||
|
||||
export const UsageCollectionName = 'usages';
|
||||
|
||||
const UsageSchema = new Schema({
|
||||
const BillSchema = new Schema({
|
||||
teamId: {
|
||||
type: Schema.Types.ObjectId,
|
||||
ref: TeamCollectionName,
|
||||
@@ -20,11 +18,6 @@ const UsageSchema = new Schema({
|
||||
ref: TeamMemberCollectionName,
|
||||
required: true
|
||||
},
|
||||
source: {
|
||||
type: String,
|
||||
enum: Object.keys(UsageSourceMap),
|
||||
required: true
|
||||
},
|
||||
appName: {
|
||||
type: String,
|
||||
default: ''
|
||||
@@ -38,16 +31,16 @@ const UsageSchema = new Schema({
|
||||
type: Date,
|
||||
default: () => new Date()
|
||||
},
|
||||
totalPoints: {
|
||||
// total points
|
||||
total: {
|
||||
// 1 * PRICE_SCALE
|
||||
type: Number,
|
||||
required: true
|
||||
},
|
||||
// total: {
|
||||
// // total points
|
||||
// type: Number,
|
||||
// required: true
|
||||
// },
|
||||
source: {
|
||||
type: String,
|
||||
enum: Object.keys(BillSourceMap),
|
||||
required: true
|
||||
},
|
||||
list: {
|
||||
type: Array,
|
||||
default: []
|
||||
@@ -55,15 +48,11 @@ const UsageSchema = new Schema({
|
||||
});
|
||||
|
||||
try {
|
||||
UsageSchema.index({ teamId: 1, tmbId: 1, source: 1, time: -1 }, { background: true });
|
||||
// timer task. clear dead team
|
||||
UsageSchema.index({ teamId: 1, time: -1 }, { background: true });
|
||||
|
||||
UsageSchema.index({ time: 1 }, { expireAfterSeconds: 180 * 24 * 60 * 60 });
|
||||
BillSchema.index({ teamId: 1, tmbId: 1, source: 1, time: -1 }, { background: true });
|
||||
BillSchema.index({ time: 1 }, { expireAfterSeconds: 180 * 24 * 60 * 60 });
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
|
||||
export const MongoUsage: Model<UsageSchemaType> =
|
||||
models[UsageCollectionName] || model(UsageCollectionName, UsageSchema);
|
||||
MongoUsage.syncIndexes();
|
||||
export const MongoBill: Model<BillType> = models['bill'] || model('bill', BillSchema);
|
||||
MongoBill.syncIndexes();
|
@@ -1,8 +1,3 @@
|
||||
/*
|
||||
user sub plan
|
||||
1. type=standard: There will only be 1, and each team will have one
|
||||
2. type=extraDatasetSize/extraPoints: Can buy multiple
|
||||
*/
|
||||
import { connectionMongo, type Model } from '../../../common/mongo';
|
||||
const { Schema, model, models } = connectionMongo;
|
||||
import { TeamCollectionName } from '@fastgpt/global/support/user/team/constant';
|
||||
@@ -28,10 +23,25 @@ const SubSchema = new Schema({
|
||||
required: true
|
||||
},
|
||||
status: {
|
||||
// active: continue sub; canceled: canceled sub;
|
||||
type: String,
|
||||
enum: Object.keys(subStatusMap),
|
||||
required: true
|
||||
},
|
||||
mode: {
|
||||
type: String,
|
||||
enum: Object.keys(subModeMap)
|
||||
},
|
||||
currentMode: {
|
||||
type: String,
|
||||
enum: Object.keys(subModeMap),
|
||||
required: true
|
||||
},
|
||||
nextMode: {
|
||||
type: String,
|
||||
enum: Object.keys(subModeMap),
|
||||
required: true
|
||||
},
|
||||
startTime: {
|
||||
type: Date,
|
||||
default: () => new Date()
|
||||
@@ -45,16 +55,12 @@ const SubSchema = new Schema({
|
||||
type: Number,
|
||||
required: true
|
||||
},
|
||||
pointPrice: {
|
||||
// stand level point total price
|
||||
type: Number
|
||||
},
|
||||
|
||||
// standard sub
|
||||
currentMode: {
|
||||
type: String,
|
||||
enum: Object.keys(subModeMap)
|
||||
},
|
||||
nextMode: {
|
||||
type: String,
|
||||
enum: Object.keys(subModeMap)
|
||||
},
|
||||
// sub content
|
||||
currentSubLevel: {
|
||||
type: String,
|
||||
enum: Object.keys(standardSubLevelMap)
|
||||
@@ -63,34 +69,79 @@ const SubSchema = new Schema({
|
||||
type: String,
|
||||
enum: Object.keys(standardSubLevelMap)
|
||||
},
|
||||
|
||||
// stand sub and extra points sub. Plan total points
|
||||
totalPoints: {
|
||||
type: Number
|
||||
},
|
||||
pointPrice: {
|
||||
// stand level point total price
|
||||
|
||||
currentExtraDatasetSize: {
|
||||
type: Number
|
||||
},
|
||||
surplusPoints: {
|
||||
// plan surplus points
|
||||
nextExtraDatasetSize: {
|
||||
type: Number
|
||||
},
|
||||
|
||||
// extra dataset size
|
||||
currentExtraDatasetSize: {
|
||||
currentExtraPoints: {
|
||||
type: Number
|
||||
}
|
||||
},
|
||||
nextExtraPoints: {
|
||||
type: Number
|
||||
},
|
||||
|
||||
// standard sub limit
|
||||
// maxTeamMember: {
|
||||
// type: Number
|
||||
// },
|
||||
// maxAppAmount: {
|
||||
// type: Number
|
||||
// },
|
||||
// maxDatasetAmount: {
|
||||
// type: Number
|
||||
// },
|
||||
// chatHistoryStoreDuration: {
|
||||
// // n day
|
||||
// type: Number
|
||||
// },
|
||||
// maxDatasetSize: {
|
||||
// type: Number
|
||||
// },
|
||||
// trainingWeight: {
|
||||
// // 0 1 2 3
|
||||
// type: Number
|
||||
// },
|
||||
// customApiKey: {
|
||||
// type: Boolean
|
||||
// },
|
||||
// customCopyright: {
|
||||
// type: Boolean
|
||||
// },
|
||||
// websiteSyncInterval: {
|
||||
// // hours
|
||||
// type: Number
|
||||
// },
|
||||
// reRankWeight: {
|
||||
// // 0 1 2 3
|
||||
// type: Number
|
||||
// },
|
||||
// totalPoints: {
|
||||
// // record standard sub points
|
||||
// type: Number
|
||||
// },
|
||||
|
||||
surplusPoints: {
|
||||
// standard sub / extra points sub
|
||||
type: Number
|
||||
},
|
||||
|
||||
// abandon
|
||||
renew: Boolean, //决定是否续费
|
||||
datasetStoreAmount: Number
|
||||
});
|
||||
|
||||
try {
|
||||
// get team plan
|
||||
SubSchema.index({ teamId: 1, type: 1, expiredTime: -1 });
|
||||
|
||||
// timer task. check expired plan; update standard plan;
|
||||
SubSchema.index({ type: 1, expiredTime: -1 });
|
||||
// timer task. clear dead team
|
||||
SubSchema.index({ type: 1, currentSubLevel: 1, nextSubLevel: 1 });
|
||||
SubSchema.index({ teamId: 1 });
|
||||
SubSchema.index({ status: 1 });
|
||||
SubSchema.index({ type: 1 });
|
||||
SubSchema.index({ expiredTime: -1 });
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
|
@@ -1,70 +1,87 @@
|
||||
import { SubTypeEnum } from '@fastgpt/global/support/wallet/sub/constants';
|
||||
import { MongoTeamSub } from './schema';
|
||||
import {
|
||||
FeTeamPlanStatusType,
|
||||
StandSubPlanLevelMapType
|
||||
} from '@fastgpt/global/support/wallet/sub/type.d';
|
||||
import { addHours } from 'date-fns';
|
||||
import { FeTeamSubType, StandSubPlanLevelMapType } from '@fastgpt/global/support/wallet/sub/type.d';
|
||||
import { getVectorCountByTeamId } from '../../../common/vectorStore/controller';
|
||||
|
||||
export const getTeamSubPlans = async ({
|
||||
teamId,
|
||||
standardPlans
|
||||
}: {
|
||||
teamId: string;
|
||||
standardPlans?: StandSubPlanLevelMapType;
|
||||
}): Promise<FeTeamPlanStatusType> => {
|
||||
const [plans, usedDatasetSize] = await Promise.all([
|
||||
MongoTeamSub.find({ teamId }).lean(),
|
||||
getVectorCountByTeamId(teamId)
|
||||
]);
|
||||
|
||||
const standard = plans.find((plan) => plan.type === SubTypeEnum.standard);
|
||||
const extraDatasetSize = plans.filter((plan) => plan.type === SubTypeEnum.extraDatasetSize);
|
||||
const extraPoints = plans.filter((plan) => plan.type === SubTypeEnum.extraPoints);
|
||||
|
||||
const totalPoints =
|
||||
(standard?.totalPoints || 0) +
|
||||
extraPoints.reduce((acc, cur) => acc + (cur.totalPoints || 0), 0);
|
||||
const surplusPoints =
|
||||
(standard?.surplusPoints || 0) +
|
||||
extraPoints.reduce((acc, cur) => acc + (cur.surplusPoints || 0), 0);
|
||||
|
||||
const standardMaxDatasetSize =
|
||||
standard?.currentSubLevel && standardPlans
|
||||
? standardPlans[standard.currentSubLevel]?.maxDatasetSize || Infinity
|
||||
: Infinity;
|
||||
const totalDatasetSize =
|
||||
standardMaxDatasetSize +
|
||||
extraDatasetSize.reduce((acc, cur) => acc + (cur.currentExtraDatasetSize || 0), 0);
|
||||
|
||||
return {
|
||||
[SubTypeEnum.standard]: standard,
|
||||
standardConstants:
|
||||
standard?.currentSubLevel && standardPlans
|
||||
? standardPlans[standard.currentSubLevel]
|
||||
: undefined,
|
||||
|
||||
totalPoints,
|
||||
usedPoints: totalPoints - surplusPoints,
|
||||
|
||||
datasetMaxSize: totalDatasetSize,
|
||||
usedDatasetSize
|
||||
};
|
||||
};
|
||||
export const getTeamStandPlan = async ({
|
||||
/* get team dataset max size */
|
||||
export const getTeamDatasetMaxSize = async ({
|
||||
teamId,
|
||||
standardPlans
|
||||
}: {
|
||||
teamId: string;
|
||||
standardPlans?: StandSubPlanLevelMapType;
|
||||
}) => {
|
||||
const standard = await MongoTeamSub.findOne({ teamId, type: SubTypeEnum.standard }).lean();
|
||||
if (!standardPlans) {
|
||||
return {
|
||||
maxSize: Infinity,
|
||||
sub: null
|
||||
};
|
||||
}
|
||||
|
||||
const plans = await MongoTeamSub.find({
|
||||
teamId,
|
||||
expiredTime: { $gte: addHours(new Date(), -3) }
|
||||
}).lean();
|
||||
|
||||
const standard = plans.find((plan) => plan.type === SubTypeEnum.standard);
|
||||
const extraDatasetSize = plans.find((plan) => plan.type === SubTypeEnum.extraDatasetSize);
|
||||
|
||||
const standardMaxDatasetSize =
|
||||
standard?.currentSubLevel && standardPlans
|
||||
? standardPlans[standard.currentSubLevel]?.maxDatasetSize || Infinity
|
||||
: Infinity;
|
||||
const totalDatasetSize =
|
||||
standardMaxDatasetSize + (extraDatasetSize?.currentExtraDatasetSize || 0);
|
||||
|
||||
return {
|
||||
maxSize: totalDatasetSize,
|
||||
sub: extraDatasetSize
|
||||
};
|
||||
};
|
||||
|
||||
export const getTeamSubPlanStatus = async ({
|
||||
teamId,
|
||||
standardPlans
|
||||
}: {
|
||||
teamId: string;
|
||||
standardPlans?: StandSubPlanLevelMapType;
|
||||
}): Promise<FeTeamSubType> => {
|
||||
const [plans, usedDatasetSize] = await Promise.all([
|
||||
MongoTeamSub.find({ teamId }).lean(),
|
||||
getVectorCountByTeamId(teamId)
|
||||
]);
|
||||
|
||||
const standard = plans.find((plan) => plan.type === SubTypeEnum.standard);
|
||||
const extraDatasetSize = plans.find((plan) => plan.type === SubTypeEnum.extraDatasetSize);
|
||||
const extraPoints = plans.find((plan) => plan.type === SubTypeEnum.extraPoints);
|
||||
|
||||
const standardMaxDatasetSize =
|
||||
standard?.currentSubLevel && standardPlans
|
||||
? standardPlans[standard.currentSubLevel]?.maxDatasetSize || Infinity
|
||||
: Infinity;
|
||||
const totalDatasetSize =
|
||||
standardMaxDatasetSize + (extraDatasetSize?.currentExtraDatasetSize || 0);
|
||||
|
||||
const standardMaxPoints =
|
||||
standard?.currentSubLevel && standardPlans
|
||||
? standardPlans[standard.currentSubLevel]?.totalPoints || Infinity
|
||||
: Infinity;
|
||||
const totalPoints = standardMaxPoints + (extraPoints?.currentExtraPoints || 0);
|
||||
|
||||
const surplusPoints = (standard?.surplusPoints || 0) + (extraPoints?.surplusPoints || 0);
|
||||
|
||||
return {
|
||||
[SubTypeEnum.standard]: standard,
|
||||
standardConstants:
|
||||
standard?.currentSubLevel && standardPlans
|
||||
? standardPlans[standard.currentSubLevel]
|
||||
: undefined
|
||||
[SubTypeEnum.extraDatasetSize]: extraDatasetSize,
|
||||
[SubTypeEnum.extraPoints]: extraPoints,
|
||||
|
||||
standardMaxDatasetSize,
|
||||
datasetMaxSize: totalDatasetSize,
|
||||
usedDatasetSize,
|
||||
|
||||
standardMaxPoints,
|
||||
totalPoints,
|
||||
usedPoints: totalPoints - surplusPoints
|
||||
};
|
||||
};
|
||||
|
@@ -5,13 +5,6 @@ export const iconPaths = {
|
||||
closeSolid: () => import('./icons/closeSolid.svg'),
|
||||
collectionLight: () => import('./icons/collectionLight.svg'),
|
||||
collectionSolid: () => import('./icons/collectionSolid.svg'),
|
||||
'acount/cube': () => import('./icons/acount/cube.svg'),
|
||||
'acount/personalized': () => import('./icons/acount/personalized.svg'),
|
||||
'acount/user': () => import('./icons/acount/user.svg'),
|
||||
'acount/plans': () => import('./icons/acount/plans.svg'),
|
||||
'acount/check': () => import('./icons/acount/check.svg'),
|
||||
'acount/arrowRight': () => import('./icons/acount/arrowRight.svg'),
|
||||
'acount/plansBlue': () => import('./icons/acount/plansBlue.svg'),
|
||||
'common/addCircleLight': () => import('./icons/common/addCircleLight.svg'),
|
||||
'common/backFill': () => import('./icons/common/backFill.svg'),
|
||||
'common/backLight': () => import('./icons/common/backLight.svg'),
|
||||
@@ -135,7 +128,6 @@ export const iconPaths = {
|
||||
kbTest: () => import('./icons/kbTest.svg'),
|
||||
menu: () => import('./icons/menu.svg'),
|
||||
minus: () => import('./icons/minus.svg'),
|
||||
'modal/confirmPay': () => import('./icons/modal/confirmPay.svg'),
|
||||
'modal/edit': () => import('./icons/modal/edit.svg'),
|
||||
'modal/manualDataset': () => import('./icons/modal/manualDataset.svg'),
|
||||
'modal/selectSource': () => import('./icons/modal/selectSource.svg'),
|
||||
@@ -151,20 +143,19 @@ export const iconPaths = {
|
||||
stop: () => import('./icons/stop.svg'),
|
||||
'support/account/loginoutLight': () => import('./icons/support/account/loginoutLight.svg'),
|
||||
'support/account/promotionLight': () => import('./icons/support/account/promotionLight.svg'),
|
||||
'support/bill/extraDatasetsize': () => import('./icons/support/bill/extraDatasetsize.svg'),
|
||||
'support/bill/extraPoints': () => import('./icons/support/bill/extraPoints.svg'),
|
||||
'support/bill/payRecordLight': () => import('./icons/support/bill/payRecordLight.svg'),
|
||||
'support/bill/priceLight': () => import('./icons/support/bill/priceLight.svg'),
|
||||
'support/bill/shoppingCart': () => import('./icons/support/bill/shoppingCart.svg'),
|
||||
'support/bill/billRecordLight': () => import('./icons/support/bill/billRecordLight.svg'),
|
||||
'support/outlink/apikeyFill': () => import('./icons/support/outlink/apikeyFill.svg'),
|
||||
'support/outlink/apikeyLight': () => import('./icons/support/outlink/apikeyLight.svg'),
|
||||
'support/outlink/iframeLight': () => import('./icons/support/outlink/iframeLight.svg'),
|
||||
'support/outlink/share': () => import('./icons/support/outlink/share.svg'),
|
||||
'support/outlink/shareLight': () => import('./icons/support/outlink/shareLight.svg'),
|
||||
'support/pay/extraDatasetsize': () => import('./icons/support/pay/extraDatasetsize.svg'),
|
||||
'support/pay/extraPoints': () => import('./icons/support/pay/extraPoints.svg'),
|
||||
'support/pay/payRecordLight': () => import('./icons/support/pay/payRecordLight.svg'),
|
||||
'support/pay/priceLight': () => import('./icons/support/pay/priceLight.svg'),
|
||||
'support/permission/privateLight': () => import('./icons/support/permission/privateLight.svg'),
|
||||
'support/permission/publicLight': () => import('./icons/support/permission/publicLight.svg'),
|
||||
'support/team/memberLight': () => import('./icons/support/team/memberLight.svg'),
|
||||
'support/usage/usageRecordLight': () => import('./icons/support/usage/usageRecordLight.svg'),
|
||||
'support/user/informLight': () => import('./icons/support/user/informLight.svg'),
|
||||
'support/user/userFill': () => import('./icons/support/user/userFill.svg'),
|
||||
'support/user/userLight': () => import('./icons/support/user/userLight.svg'),
|
||||
|
@@ -1,3 +0,0 @@
|
||||
<svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M6.64645 2.64645C6.45118 2.84171 6.45118 3.15829 6.64645 3.35355L8.79289 5.5H2C1.72386 5.5 1.5 5.72386 1.5 6C1.5 6.27614 1.72386 6.5 2 6.5H8.79289L6.64645 8.64645C6.45118 8.84171 6.45118 9.15829 6.64645 9.35355C6.84171 9.54882 7.15829 9.54882 7.35355 9.35355L10.3536 6.35355C10.5488 6.15829 10.5488 5.84171 10.3536 5.64645L7.35355 2.64645C7.15829 2.45118 6.84171 2.45118 6.64645 2.64645Z" fill="#2B5FD9"/>
|
||||
</svg>
|
Before Width: | Height: | Size: 558 B |
@@ -1,3 +0,0 @@
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M12.6262 3.29289C13.0167 2.90237 13.6499 2.90237 14.0404 3.29289C14.4309 3.68342 14.4309 4.31658 14.0404 4.70711L6.70707 12.0404C6.31654 12.431 5.68338 12.431 5.29285 12.0404L1.95952 8.70711C1.56899 8.31658 1.56899 7.68342 1.95952 7.29289C2.35004 6.90237 2.98321 6.90237 3.37373 7.29289L5.99996 9.91912L12.6262 3.29289Z" fill="#3370FF"/>
|
||||
</svg>
|
Before Width: | Height: | Size: 490 B |
@@ -1,3 +0,0 @@
|
||||
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M9.66427 0.987294C9.88579 0.941735 10.1143 0.941735 10.3358 0.987294C10.5918 1.03996 10.8207 1.16815 11.0027 1.27006C11.0196 1.27955 11.0361 1.28881 11.0523 1.29776L17.2189 4.72369C17.236 4.73316 17.2535 4.74284 17.2715 4.75275C17.4641 4.85884 17.7063 4.99223 17.8923 5.19405C18.0531 5.36853 18.1748 5.57534 18.2492 5.80063C18.3353 6.06121 18.3343 6.33769 18.3335 6.55759C18.3334 6.57814 18.3334 6.5982 18.3334 6.6177V13.382C18.3334 13.4015 18.3334 13.4215 18.3335 13.4421C18.3343 13.662 18.3353 13.9384 18.2492 14.199C18.1748 14.4243 18.0531 14.6311 17.8923 14.8056C17.7063 15.0074 17.4641 15.1408 17.2715 15.2469C17.2535 15.2568 17.236 15.2665 17.2189 15.276L11.0522 18.7019C11.0361 18.7108 11.0196 18.7201 11.0026 18.7296C10.8207 18.8315 10.5918 18.9597 10.3358 19.0124C10.1143 19.0579 9.88579 19.0579 9.66427 19.0124C9.40821 18.9597 9.17934 18.8315 8.99739 18.7296C8.98045 18.7201 8.96391 18.7108 8.9478 18.7019L2.78113 15.276C2.76408 15.2665 2.74652 15.2568 2.72852 15.2469C2.53591 15.1408 2.29373 15.0074 2.10774 14.8056C1.94695 14.6311 1.82527 14.4243 1.75083 14.199C1.66473 13.9384 1.66574 13.662 1.66654 13.4421C1.66662 13.4215 1.66669 13.4015 1.66669 13.382V6.6177C1.66669 6.5982 1.66662 6.57814 1.66654 6.55759C1.66574 6.3377 1.66473 6.06121 1.75083 5.80063C1.82527 5.57534 1.94695 5.36853 2.10774 5.19405C2.29372 4.99223 2.5359 4.85884 2.72851 4.75275C2.74651 4.74284 2.76408 4.73316 2.78113 4.72369L8.9478 1.29776C8.96391 1.28881 8.98045 1.27955 8.99739 1.27006C9.17934 1.16815 9.40821 1.03996 9.66427 0.987294ZM10 2.62398C9.99876 2.62459 9.99743 2.62522 9.99604 2.62589C9.94795 2.64909 9.88349 2.68453 9.7572 2.75469L4.21597 5.83316L10 9.0465L15.784 5.83314L10.2428 2.75469C10.1166 2.68453 10.0521 2.64909 10.004 2.62589C10.0026 2.62522 10.0013 2.62459 10 2.62398ZM16.6667 7.24938V13.382C16.6667 13.5344 16.6663 13.6125 16.6629 13.669C16.6628 13.6707 16.6627 13.6722 16.6626 13.6738C16.6614 13.6746 16.66 13.6755 16.6586 13.6764C16.6109 13.7068 16.5428 13.745 16.4095 13.819L10.8334 16.9169L10.8333 10.4901L16.6667 7.24938ZM9.16667 10.4901L3.33336 7.24941V13.382C3.33336 13.5344 3.3337 13.6125 3.33711 13.669C3.33721 13.6707 3.33731 13.6722 3.33741 13.6738C3.33869 13.6746 3.34003 13.6755 3.34144 13.6764C3.38919 13.7068 3.45724 13.745 3.59054 13.819L9.16669 16.9169L9.16667 10.4901Z" fill="black"/>
|
||||
</svg>
|
Before Width: | Height: | Size: 2.4 KiB |
@@ -1,3 +0,0 @@
|
||||
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M8.95334 16.4281C9.05498 16.5828 8.93673 16.8071 8.75405 16.777C7.16443 16.5146 5.94181 15.8533 5.05187 14.9994C3.73702 13.7379 3.01725 11.931 3.01725 9.9769C3.01725 6.18011 6.09515 3.10221 9.89194 3.10221C13.8727 3.10221 16.9827 5.87983 16.9827 9.50285C16.9827 10.4282 16.7524 10.9955 16.4763 11.3538C16.1992 11.7133 15.7615 12.011 15.0821 12.191C14.485 12.3493 13.879 12.3607 13.0988 12.3754C12.9461 12.3782 12.7868 12.3812 12.6195 12.3855C11.7922 12.4065 10.4224 12.4464 9.36346 13.3001C8.72411 13.8156 8.524 14.5121 8.52868 15.0653C8.5328 15.5521 8.68681 15.9446 8.79908 16.1635C8.84683 16.2566 8.89859 16.3447 8.95334 16.4281ZM15.5091 13.8021C17.4217 13.2951 18.6494 11.9261 18.6494 9.50285C18.6494 4.7856 14.6092 1.43555 9.89194 1.43555C5.17468 1.43555 1.35059 5.25964 1.35059 9.9769C1.35059 14.6942 4.8343 19.0091 11.2788 18.5298C12.2308 18.459 12.5569 17.3597 12.122 16.8903C11.89 16.6399 11.5858 16.4575 11.2857 16.2776C10.8812 16.035 10.4842 15.797 10.2821 15.4029C10.214 15.2701 10.0763 14.8663 10.4095 14.5977C11.0553 14.0771 12.0167 14.0611 13.082 14.0434C13.8631 14.0304 14.7 14.0165 15.5091 13.8021ZM6.85887 9.40095C6.85887 10.1411 6.25883 10.7412 5.51863 10.7412C4.77844 10.7412 4.1784 10.1411 4.1784 9.40095C4.1784 8.66076 4.77844 8.06071 5.51863 8.06071C6.25883 8.06071 6.85887 8.66076 6.85887 9.40095ZM8.09584 7.52192C8.83604 7.52192 9.43608 6.92187 9.43608 6.18168C9.43608 5.44149 8.83604 4.84144 8.09584 4.84144C7.35565 4.84144 6.75561 5.44149 6.75561 6.18168C6.75561 6.92187 7.35565 7.52192 8.09584 7.52192ZM13.4525 6.18168C13.4525 6.92187 12.8525 7.52192 12.1123 7.52192C11.3721 7.52192 10.772 6.92187 10.772 6.18168C10.772 5.44149 11.3721 4.84144 12.1123 4.84144C12.8525 4.84144 13.4525 5.44149 13.4525 6.18168ZM14.4814 10.7412C15.2216 10.7412 15.8216 10.1411 15.8216 9.40095C15.8216 8.66076 15.2216 8.06071 14.4814 8.06071C13.7412 8.06071 13.1411 8.66076 13.1411 9.40095C13.1411 10.1411 13.7412 10.7412 14.4814 10.7412Z" fill="black"/>
|
||||
</svg>
|
Before Width: | Height: | Size: 2.1 KiB |
@@ -1,5 +0,0 @@
|
||||
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M15.4622 17.4792C15.9398 17.4524 16.2747 17.3901 16.5593 17.245C16.9984 17.0213 17.3553 16.6644 17.579 16.2253C17.8334 15.7262 17.8334 15.0728 17.8334 13.766V6.23268C17.8334 4.92589 17.8334 4.2725 17.579 3.77337C17.3553 3.33433 16.9984 2.97737 16.5593 2.75367C16.2747 2.60862 15.9398 2.5463 15.4622 2.51952C15.4647 2.72072 15.4647 2.94567 15.4647 3.19935V4.02265C15.4802 4.02376 15.4954 4.02493 15.5104 4.02616C15.8016 4.04995 15.873 4.08738 15.8781 4.09007C16.0349 4.16996 16.1626 4.29756 16.2425 4.45436C16.2452 4.45947 16.2828 4.53114 16.3065 4.8223C16.3322 5.13614 16.3334 5.55454 16.3334 6.23268V13.766C16.3334 14.4442 16.3322 14.8626 16.3065 15.1764C16.2828 15.4676 16.2453 15.539 16.2426 15.5441C16.1627 15.7009 16.0351 15.8286 15.8783 15.9085C15.8732 15.9112 15.8015 15.9488 15.5104 15.9725C15.4954 15.9738 15.4802 15.9749 15.4647 15.976V16.7993C15.4647 17.053 15.4647 17.278 15.4622 17.4792Z" fill="#111824"/>
|
||||
<path d="M4.53531 17.479C4.05904 17.4522 3.72487 17.3898 3.44071 17.245C3.00166 17.0213 2.64471 16.6644 2.421 16.2253C2.16669 15.7262 2.16669 15.0728 2.16669 13.766V6.23268C2.16669 4.92589 2.16669 4.2725 2.421 3.77337C2.64471 3.33433 3.00166 2.97737 3.44071 2.75367C3.72487 2.60888 4.05904 2.54652 4.53531 2.51966V4.02265C4.51984 4.02376 4.50462 4.02493 4.48964 4.02616C4.19848 4.04994 4.12702 4.08738 4.12191 4.09007C3.9651 4.16996 3.83741 4.29755 3.75752 4.45436C3.75483 4.45947 3.71728 4.53114 3.69349 4.8223C3.66785 5.13614 3.66669 5.55454 3.66669 6.23268V13.766C3.66669 14.4442 3.66785 14.8626 3.69349 15.1764C3.71728 15.4676 3.75472 15.539 3.75741 15.5441C3.8373 15.7009 3.96489 15.8286 4.12169 15.9085C4.12682 15.9112 4.1985 15.9488 4.48964 15.9725C4.50462 15.9738 4.51984 15.9749 4.53531 15.976V17.479Z" fill="#111824"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M11.4577 3.33268H8.5423C7.95474 3.33268 7.61431 3.33398 7.36442 3.3544C7.25432 3.36339 7.19609 3.37413 7.17186 3.37955C7.12412 3.40795 7.08423 3.44784 7.05583 3.49558C7.05041 3.51981 7.03967 3.57804 7.03068 3.68814C7.01026 3.93803 7.00896 4.27846 7.00896 4.86602V15.1327C7.00896 15.7202 7.01026 16.0607 7.03068 16.3106C7.03967 16.4207 7.05041 16.4789 7.05583 16.5031C7.08423 16.5509 7.12412 16.5907 7.17187 16.6192C7.19609 16.6246 7.25432 16.6353 7.36442 16.6443C7.61431 16.6647 7.95474 16.666 8.5423 16.666H11.4577C12.0453 16.666 12.3857 16.6647 12.6356 16.6443C12.7457 16.6353 12.8039 16.6246 12.8282 16.6191C12.8759 16.5907 12.9158 16.5509 12.9442 16.5031C12.9496 16.4789 12.9604 16.4207 12.9694 16.3106C12.9898 16.0607 12.9911 15.7202 12.9911 15.1327V4.86602C12.9911 4.27846 12.9898 3.93803 12.9694 3.68814C12.9604 3.57804 12.9496 3.51981 12.9442 3.49558C12.9158 3.44784 12.8759 3.40795 12.8282 3.37955C12.8039 3.37413 12.7457 3.36339 12.6356 3.3544C12.3857 3.33398 12.0453 3.33268 11.4577 3.33268ZM12.8421 3.38304L12.8408 3.38266L12.8421 3.38304ZM12.9407 16.517L12.9411 16.5157L12.9407 16.517ZM7.15797 16.6157L7.15924 16.616L7.15797 16.6157ZM5.56028 2.75803C5.3423 3.18586 5.3423 3.74591 5.3423 4.86602V15.1327C5.3423 16.2528 5.3423 16.8128 5.56028 17.2407C5.75203 17.617 6.05799 17.9229 6.43432 18.1147C6.86214 18.3327 7.42219 18.3327 8.5423 18.3327H11.4577C12.5778 18.3327 13.1379 18.3327 13.5657 18.1147C13.942 17.9229 14.248 17.617 14.4397 17.2407C14.6577 16.8128 14.6577 16.2528 14.6577 15.1327V4.86602C14.6577 3.74591 14.6577 3.18586 14.4397 2.75803C14.248 2.38171 13.942 2.07575 13.5657 1.884C13.1379 1.66602 12.5778 1.66602 11.4577 1.66602H8.5423C7.42219 1.66602 6.86214 1.66602 6.43432 1.884C6.05799 2.07575 5.75203 2.38171 5.56028 2.75803Z" fill="#111824"/>
|
||||
</svg>
|
Before Width: | Height: | Size: 3.6 KiB |
@@ -1,5 +0,0 @@
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M18.5546 20.9758C19.1277 20.9437 19.5295 20.8689 19.8711 20.6948C20.398 20.4264 20.8263 19.998 21.0948 19.4712C21.4 18.8722 21.4 18.0881 21.4 16.52V7.48C21.4 5.91185 21.4 5.12778 21.0948 4.52883C20.8263 4.00197 20.398 3.57363 19.8711 3.30518C19.5295 3.13113 19.1277 3.05634 18.5546 3.02421C18.5576 3.26564 18.5576 3.53559 18.5576 3.84V4.82796C18.5762 4.8293 18.5945 4.8307 18.6124 4.83217C18.9618 4.86072 19.0476 4.90564 19.0537 4.90886C19.2419 5.00473 19.3951 5.15785 19.491 5.34601C19.4942 5.35215 19.5393 5.43815 19.5678 5.78754C19.5986 6.16415 19.6 6.66622 19.6 7.48V16.52C19.6 17.3338 19.5986 17.8359 19.5678 18.2125C19.5393 18.5619 19.4943 18.6476 19.4911 18.6537C19.3952 18.8419 19.2421 18.9951 19.054 19.091C19.0478 19.0942 18.9618 19.1393 18.6124 19.1678C18.5945 19.1693 18.5762 19.1707 18.5576 19.172V20.16C18.5576 20.4644 18.5576 20.7344 18.5546 20.9758Z" fill="#3370FF"/>
|
||||
<path d="M5.44233 20.9756C4.8708 20.9434 4.4698 20.8686 4.1288 20.6948C3.60195 20.4264 3.1736 19.998 2.90516 19.4712C2.59998 18.8722 2.59998 18.0881 2.59998 16.52V7.48C2.59998 5.91185 2.59998 5.12778 2.90516 4.52883C3.1736 4.00197 3.60195 3.57363 4.1288 3.30518C4.4698 3.13143 4.8708 3.0566 5.44233 3.02438V4.82796C5.42376 4.8293 5.4055 4.8307 5.38752 4.83217C5.03813 4.86071 4.95238 4.90564 4.94624 4.90886C4.75808 5.00473 4.60484 5.15785 4.50897 5.34601C4.50575 5.35215 4.46069 5.43815 4.43215 5.78754C4.40138 6.16415 4.39998 6.66622 4.39998 7.48V16.52C4.39998 17.3338 4.40138 17.8358 4.43215 18.2125C4.46069 18.5619 4.50562 18.6476 4.50884 18.6537C4.60471 18.8419 4.75782 18.9951 4.94598 19.091C4.95214 19.0942 5.03815 19.1393 5.38752 19.1678C5.4055 19.1693 5.42376 19.1707 5.44233 19.172V20.9756Z" fill="#3370FF"/>
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M13.7492 4H10.2507C9.54564 4 9.13713 4.00156 8.83726 4.02606C8.70514 4.03685 8.63526 4.04974 8.60619 4.05624C8.5489 4.09032 8.50103 4.13819 8.46694 4.19548C8.46044 4.22455 8.44756 4.29443 8.43676 4.42655C8.41226 4.72642 8.41071 5.13494 8.41071 5.84V18.16C8.41071 18.8651 8.41226 19.2736 8.43676 19.5735C8.44756 19.7056 8.46044 19.7754 8.46694 19.8045C8.50103 19.8618 8.5489 19.9097 8.60619 19.9438C8.63526 19.9503 8.70514 19.9632 8.83726 19.9739C9.13713 19.9984 9.54564 20 10.2507 20H13.7492C14.4543 20 14.8628 19.9984 15.1627 19.9739C15.2948 19.9631 15.3647 19.9503 15.3938 19.9438C15.451 19.9097 15.4989 19.8618 15.533 19.8045C15.5395 19.7754 15.5524 19.7056 15.5632 19.5735C15.5877 19.2736 15.5892 18.8651 15.5892 18.16V5.84C15.5892 5.13494 15.5877 4.72642 15.5632 4.42655C15.5524 4.29443 15.5395 4.22455 15.533 4.19548C15.4989 4.13819 15.451 4.09032 15.3938 4.05624C15.3647 4.04974 15.2948 4.03685 15.1627 4.02606C14.8628 4.00156 14.4543 4 13.7492 4ZM15.4104 4.06043L15.4089 4.05997L15.4104 4.06043ZM15.5288 19.8212L15.5293 19.8197L15.5288 19.8212ZM8.58952 19.9396L8.59104 19.94L8.58952 19.9396ZM6.67229 3.31042C6.41071 3.82381 6.41071 4.49587 6.41071 5.84V18.16C6.41071 19.5041 6.41071 20.1762 6.67229 20.6896C6.90239 21.1412 7.26954 21.5083 7.72113 21.7384C8.23452 22 8.90658 22 10.2507 22H13.7492C15.0934 22 15.7654 22 16.2788 21.7384C16.7304 21.5083 17.0976 21.1412 17.3277 20.6896C17.5892 20.1762 17.5892 19.5041 17.5892 18.16V5.84C17.5892 4.49587 17.5892 3.82381 17.3277 3.31042C17.0976 2.85883 16.7304 2.49168 16.2788 2.26158C15.7654 2 15.0934 2 13.7492 2H10.2507C8.90658 2 8.23452 2 7.72113 2.26158C7.26954 2.49168 6.90239 2.85883 6.67229 3.31042Z" fill="#3370FF"/>
|
||||
</svg>
|
Before Width: | Height: | Size: 3.5 KiB |
@@ -1,3 +0,0 @@
|
||||
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M10 3.33268C8.38917 3.33268 7.08333 4.63852 7.08333 6.24935C7.08333 7.86018 8.38917 9.16602 10 9.16602C11.6108 9.16602 12.9167 7.86018 12.9167 6.24935C12.9167 4.63852 11.6108 3.33268 10 3.33268ZM5.41667 6.24935C5.41667 3.71804 7.46869 1.66602 10 1.66602C12.5313 1.66602 14.5833 3.71804 14.5833 6.24935C14.5833 8.78065 12.5313 10.8327 10 10.8327C7.46869 10.8327 5.41667 8.78065 5.41667 6.24935ZM10 13.3327C7.63414 13.3327 5.5254 14.4737 4.1782 16.2567C4.09579 16.3658 4.03271 16.4494 3.98025 16.5228C3.94042 16.5786 3.91323 16.6195 3.89431 16.6505C4.01816 16.6647 4.19464 16.666 4.52269 16.666H15.4773C15.8054 16.666 15.9818 16.6647 16.1057 16.6505C16.0868 16.6195 16.0596 16.5786 16.0197 16.5228C15.9673 16.4494 15.9042 16.3658 15.8218 16.2567C14.4746 14.4737 12.3659 13.3327 10 13.3327ZM2.84845 15.2519C4.49259 13.076 7.0824 11.666 10 11.666C12.9176 11.666 15.5074 13.076 17.1515 15.2519C17.159 15.2618 17.1664 15.2717 17.1739 15.2816C17.3153 15.4685 17.4669 15.669 17.5752 15.8623C17.7063 16.0964 17.8035 16.3672 17.7975 16.6965C17.7926 16.9612 17.7124 17.209 17.615 17.4047C17.5176 17.6003 17.3683 17.8137 17.16 17.9772C16.8822 18.1951 16.5798 18.2723 16.3111 18.3045C16.0754 18.3328 15.7961 18.3327 15.5153 18.3327C15.5026 18.3327 15.49 18.3327 15.4773 18.3327H4.52269C4.51003 18.3327 4.49737 18.3327 4.48472 18.3327C4.20389 18.3327 3.92457 18.3328 3.68887 18.3045C3.42021 18.2723 3.11779 18.1951 2.84002 17.9772C2.63173 17.8137 2.48237 17.6003 2.38498 17.4047C2.28758 17.209 2.20738 16.9612 2.20254 16.6965C2.19651 16.3672 2.29369 16.0964 2.4248 15.8623C2.53312 15.669 2.68469 15.4685 2.82606 15.2816C2.83355 15.2717 2.84102 15.2618 2.84845 15.2519Z" fill="black"/>
|
||||
</svg>
|
Before Width: | Height: | Size: 1.8 KiB |
@@ -1,5 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd"
|
||||
d="M15.277 4.64527C13.6911 3.93863 11.9193 3.76357 10.2257 4.1462C8.5322 4.52883 7.00773 5.44865 5.87967 6.76847C4.75162 8.08829 4.08042 9.73741 3.96618 11.4699C3.85195 13.2023 4.30079 14.9253 5.24577 16.3818C6.19076 17.8383 7.58125 18.9503 9.20987 19.552C10.8385 20.1537 12.618 20.2128 14.2829 19.7206C15.9479 19.2283 17.4091 18.211 18.4487 16.8204C19.4883 15.4298 20.0505 13.7404 20.0515 12.0042V11.1721C20.0515 10.6198 20.4992 10.1721 21.0515 10.1721C21.6037 10.1721 22.0515 10.6198 22.0515 11.1721V12.0048C22.0502 14.1723 21.3484 16.2819 20.0506 18.0179C18.7528 19.7539 16.9286 21.0239 14.85 21.6385C12.7715 22.253 10.5499 22.1792 8.51676 21.4281C6.48359 20.6769 4.74769 19.2887 3.56797 17.4704C2.38824 15.652 1.8279 13.5011 1.97052 11.3383C2.11313 9.17546 2.95106 7.1167 4.35933 5.46903C5.7676 3.82136 7.67076 2.67305 9.78496 2.19537C11.8992 1.7177 14.1111 1.93624 16.091 2.81841C16.5955 3.04319 16.8222 3.63437 16.5974 4.13884C16.3727 4.64331 15.7815 4.87005 15.277 4.64527ZM21.7582 4.05106C22.1489 4.44138 22.1492 5.07455 21.7589 5.46527L12.7076 14.5257C12.5201 14.7134 12.2656 14.8189 12.0003 14.8189C11.735 14.819 11.4806 14.7136 11.293 14.526L8.57758 11.8106C8.18705 11.4201 8.18705 10.7869 8.57758 10.3964C8.9681 10.0059 9.60127 10.0059 9.99179 10.3964L11.9997 12.4044L20.344 4.05176C20.7343 3.66104 21.3675 3.66073 21.7582 4.05106Z"
|
||||
fill="#3370FF" />
|
||||
</svg>
|
Before Width: | Height: | Size: 1.5 KiB |
Before Width: | Height: | Size: 2.6 KiB After Width: | Height: | Size: 2.6 KiB |
@@ -1,4 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 18 18" fill="none">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd"
|
||||
d="M1.00332 1.83758H1.81954L2.53389 13.2672C2.53944 13.3565 2.54623 13.466 2.56003 13.5627C2.5762 13.6759 2.60963 13.8372 2.70433 14.0046C2.8274 14.2221 3.01365 14.397 3.23839 14.5063C3.41135 14.5904 3.5744 14.6137 3.68844 14.6228C3.78573 14.6305 3.89538 14.6304 3.98486 14.6304L14.5957 14.6304C15.0559 14.6304 15.429 14.2573 15.429 13.7971C15.429 13.3368 15.0559 12.9637 14.5957 12.9637H4.18485L4.08913 11.4322H13.9345C14.314 11.4322 14.6453 11.4322 14.9207 11.4108C15.2135 11.3881 15.5068 11.3377 15.7953 11.2025C16.2272 11.0002 16.5901 10.6754 16.8389 10.2685C17.0051 9.99663 17.0875 9.71073 17.1425 9.42221C17.1942 9.1509 17.2308 8.82158 17.2727 8.44437L17.7459 4.18496C17.7576 4.08038 17.7715 3.95605 17.7743 3.84616C17.7775 3.72047 17.7706 3.53205 17.6864 3.32954C17.5794 3.07183 17.388 2.85804 17.1437 2.72315C16.9517 2.61716 16.7652 2.58946 16.6399 2.57879C16.5304 2.56947 16.4053 2.56952 16.3001 2.56956L3.53521 2.56956L3.4705 1.53411C3.46496 1.44478 3.45816 1.3353 3.44436 1.23865C3.4282 1.12539 3.39476 0.964112 3.30006 0.796741C3.17699 0.579249 2.99074 0.404282 2.766 0.29502C2.59305 0.210937 2.42999 0.187632 2.31595 0.178561C2.21863 0.170821 2.10894 0.170867 2.01944 0.170904L1.00332 0.170909C0.543079 0.170909 0.169983 0.544005 0.169983 1.00424C0.169983 1.46448 0.543079 1.83758 1.00332 1.83758ZM13.9048 9.76553H3.98496L3.63938 4.23623H16.0633L15.6195 8.23082C15.5733 8.64611 15.5434 8.91032 15.5053 9.11032C15.4691 9.30015 15.4364 9.36731 15.4169 9.39917C15.3386 9.52728 15.2243 9.62954 15.0884 9.69323C15.0545 9.70907 14.9842 9.73419 14.7915 9.74917C14.5885 9.76495 14.3226 9.76553 13.9048 9.76553ZM5.40085 15.3624C4.71982 15.3624 4.16774 15.9145 4.16774 16.5955C4.16774 17.2765 4.71983 17.8286 5.40085 17.8286C6.08188 17.8286 6.63396 17.2765 6.63396 16.5955C6.63396 15.9145 6.08188 15.3624 5.40085 15.3624ZM12.5968 15.3624C11.9158 15.3624 11.3637 15.9145 11.3637 16.5955C11.3637 17.2765 11.9158 17.8286 12.5968 17.8286C13.2778 17.8286 13.8299 17.2765 13.8299 16.5955C13.8299 15.9145 13.2778 15.3624 12.5968 15.3624Z" />
|
||||
</svg>
|
Before Width: | Height: | Size: 2.1 KiB |
Before Width: | Height: | Size: 4.4 KiB After Width: | Height: | Size: 4.4 KiB |