Compare commits
8 Commits
v4.9.4
...
v4.9.5-alp
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
16a22bc76a | ||
|
|
b51a87f5b7 | ||
|
|
bc1ca66b66 | ||
|
|
c9e12bb608 | ||
|
|
4e7fa29087 | ||
|
|
ec3bcfa124 | ||
|
|
199f454b6b | ||
|
|
80f41dd2a9 |
3
.github/workflows/fastgpt-test.yaml
vendored
3
.github/workflows/fastgpt-test.yaml
vendored
@@ -15,6 +15,9 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
ref: ${{ github.event.pull_request.head.ref }}
|
||||||
|
repository: ${{ github.event.pull_request.head.repo.full_name }}
|
||||||
- uses: pnpm/action-setup@v4
|
- uses: pnpm/action-setup@v4
|
||||||
with:
|
with:
|
||||||
version: 10
|
version: 10
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
<a href="./README_ja.md">日语</a>
|
<a href="./README_ja.md">日语</a>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
FastGPT 是一个基于 LLM 大语言模型的知识库问答系统,提供开箱即用的数据处理、模型调用等能力。同时可以通过 Flow 可视化进行工作流编排,从而实现复杂的问答场景!
|
FastGPT 是一个 AI Agent 构建平台,提供开箱即用的数据处理、模型调用等能力,同时可以通过 Flow 可视化进行工作流编排,从而实现复杂的应用场景!
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -126,15 +126,15 @@ services:
|
|||||||
# fastgpt
|
# fastgpt
|
||||||
sandbox:
|
sandbox:
|
||||||
container_name: sandbox
|
container_name: sandbox
|
||||||
image: ghcr.io/labring/fastgpt-sandbox:v4.9.3 # git
|
image: ghcr.io/labring/fastgpt-sandbox:v4.9.4 # git
|
||||||
# image: registry.cn-hangzhou.aliyuncs.com/fastgpt/fastgpt-sandbox:v4.9.3 # 阿里云
|
# image: registry.cn-hangzhou.aliyuncs.com/fastgpt/fastgpt-sandbox:v4.9.4 # 阿里云
|
||||||
networks:
|
networks:
|
||||||
- fastgpt
|
- fastgpt
|
||||||
restart: always
|
restart: always
|
||||||
fastgpt:
|
fastgpt:
|
||||||
container_name: fastgpt
|
container_name: fastgpt
|
||||||
image: ghcr.io/labring/fastgpt:v4.9.3 # git
|
image: ghcr.io/labring/fastgpt:v4.9.4 # git
|
||||||
# image: registry.cn-hangzhou.aliyuncs.com/fastgpt/fastgpt:v4.9.3 # 阿里云
|
# image: registry.cn-hangzhou.aliyuncs.com/fastgpt/fastgpt:v4.9.4 # 阿里云
|
||||||
ports:
|
ports:
|
||||||
- 3000:3000
|
- 3000:3000
|
||||||
networks:
|
networks:
|
||||||
@@ -184,6 +184,8 @@ services:
|
|||||||
- ALLOWED_ORIGINS=
|
- ALLOWED_ORIGINS=
|
||||||
# 是否开启IP限制,默认不开启
|
# 是否开启IP限制,默认不开启
|
||||||
- USE_IP_LIMIT=false
|
- USE_IP_LIMIT=false
|
||||||
|
# 对话文件过期天数
|
||||||
|
- CHAT_FILE_EXPIRE_TIME=7
|
||||||
volumes:
|
volumes:
|
||||||
- ./config.json:/app/data/config.json
|
- ./config.json:/app/data/config.json
|
||||||
|
|
||||||
|
|||||||
202
deploy/docker/docker-compose-oceanbase/docker-compose.yml
Normal file
202
deploy/docker/docker-compose-oceanbase/docker-compose.yml
Normal file
@@ -0,0 +1,202 @@
|
|||||||
|
# 数据库的默认账号和密码仅首次运行时设置有效
|
||||||
|
# 如果修改了账号密码,记得改数据库和项目连接参数,别只改一处~
|
||||||
|
# 该配置文件只是给快速启动,测试使用。正式使用,记得务必修改账号密码,以及调整合适的知识库参数,共享内存等。
|
||||||
|
# 如何无法访问 dockerhub 和 git,可以用阿里云(阿里云没有arm包)
|
||||||
|
|
||||||
|
version: '3.3'
|
||||||
|
services:
|
||||||
|
# vector db
|
||||||
|
ob:
|
||||||
|
image: oceanbase/oceanbase-ce # docker hub
|
||||||
|
# image: quay.io/oceanbase/oceanbase-ce:4.3.5.1-101000042025031818 # 镜像
|
||||||
|
container_name: ob
|
||||||
|
restart: always
|
||||||
|
# ports: # 生产环境建议不要暴露
|
||||||
|
# - 2881:2881
|
||||||
|
networks:
|
||||||
|
- fastgpt
|
||||||
|
environment:
|
||||||
|
# 这里的配置只有首次运行生效。修改后,重启镜像是不会生效的。需要把持久化数据删除再重启,才有效果
|
||||||
|
- OB_SYS_PASSWORD=obsyspassword
|
||||||
|
# 不同于传统数据库,OceanBase 数据库的账号包含更多字段,包括用户名、租户名和集群名。经典格式为“用户名@租户名#集群名”
|
||||||
|
# 比如用mysql客户端连接时,根据本文件的默认配置,应该指定 “-uroot@tenantname”
|
||||||
|
- OB_TENANT_NAME=tenantname
|
||||||
|
- OB_TENANT_PASSWORD=tenantpassword
|
||||||
|
# MODE分为MINI和NORMAL, 后者会最大程度使用主机资源
|
||||||
|
- MODE=NORMAL
|
||||||
|
- OB_SERVER_IP=127.0.0.1
|
||||||
|
# 更多环境变量配置见oceanbase官方文档: https://www.oceanbase.com/docs/common-oceanbase-database-cn-1000000002013494
|
||||||
|
volumes:
|
||||||
|
- ./ob/data:/root/ob
|
||||||
|
- ./ob/config:/root/.obd/cluster
|
||||||
|
- ./init.sql:/root/boot/init.d/init.sql
|
||||||
|
healthcheck:
|
||||||
|
# obclient -h127.0.0.1 -P2881 -uroot@tenantname -ptenantpassword -e "SELECT 1;"
|
||||||
|
test: ["CMD-SHELL", "obclient -h$OB_SERVER_IP -P2881 -uroot@$OB_TENANT_NAME -p$OB_TENANT_PASSWORD -e \"SELECT 1;\""]
|
||||||
|
interval: 30s
|
||||||
|
timeout: 10s
|
||||||
|
retries: 1000
|
||||||
|
start_period: 10s
|
||||||
|
mongo:
|
||||||
|
image: mongo:5.0.18 # dockerhub
|
||||||
|
# image: registry.cn-hangzhou.aliyuncs.com/fastgpt/mongo:5.0.18 # 阿里云
|
||||||
|
# image: mongo:4.4.29 # cpu不支持AVX时候使用
|
||||||
|
container_name: mongo
|
||||||
|
restart: always
|
||||||
|
# ports:
|
||||||
|
# - 27017:27017
|
||||||
|
networks:
|
||||||
|
- fastgpt
|
||||||
|
command: mongod --keyFile /data/mongodb.key --replSet rs0
|
||||||
|
environment:
|
||||||
|
- MONGO_INITDB_ROOT_USERNAME=myusername
|
||||||
|
- MONGO_INITDB_ROOT_PASSWORD=mypassword
|
||||||
|
volumes:
|
||||||
|
- ./mongo/data:/data/db
|
||||||
|
entrypoint:
|
||||||
|
- bash
|
||||||
|
- -c
|
||||||
|
- |
|
||||||
|
openssl rand -base64 128 > /data/mongodb.key
|
||||||
|
chmod 400 /data/mongodb.key
|
||||||
|
chown 999:999 /data/mongodb.key
|
||||||
|
echo 'const isInited = rs.status().ok === 1
|
||||||
|
if(!isInited){
|
||||||
|
rs.initiate({
|
||||||
|
_id: "rs0",
|
||||||
|
members: [
|
||||||
|
{ _id: 0, host: "mongo:27017" }
|
||||||
|
]
|
||||||
|
})
|
||||||
|
}' > /data/initReplicaSet.js
|
||||||
|
# 启动MongoDB服务
|
||||||
|
exec docker-entrypoint.sh "$$@" &
|
||||||
|
|
||||||
|
# 等待MongoDB服务启动
|
||||||
|
until mongo -u myusername -p mypassword --authenticationDatabase admin --eval "print('waited for connection')"; do
|
||||||
|
echo "Waiting for MongoDB to start..."
|
||||||
|
sleep 2
|
||||||
|
done
|
||||||
|
|
||||||
|
# 执行初始化副本集的脚本
|
||||||
|
mongo -u myusername -p mypassword --authenticationDatabase admin /data/initReplicaSet.js
|
||||||
|
|
||||||
|
# 等待docker-entrypoint.sh脚本执行的MongoDB服务进程
|
||||||
|
wait $$!
|
||||||
|
|
||||||
|
# fastgpt
|
||||||
|
sandbox:
|
||||||
|
container_name: sandbox
|
||||||
|
image: ghcr.io/labring/fastgpt-sandbox:v4.9.3 # git
|
||||||
|
# image: registry.cn-hangzhou.aliyuncs.com/fastgpt/fastgpt-sandbox:v4.9.3 # 阿里云
|
||||||
|
networks:
|
||||||
|
- fastgpt
|
||||||
|
restart: always
|
||||||
|
fastgpt:
|
||||||
|
container_name: fastgpt
|
||||||
|
image: ghcr.io/labring/fastgpt:v4.9.3 # git
|
||||||
|
# image: registry.cn-hangzhou.aliyuncs.com/fastgpt/fastgpt:v4.9.3 # 阿里云
|
||||||
|
ports:
|
||||||
|
- 3000:3000
|
||||||
|
networks:
|
||||||
|
- fastgpt
|
||||||
|
depends_on:
|
||||||
|
mongo:
|
||||||
|
condition: service_started
|
||||||
|
ob:
|
||||||
|
condition: service_healthy
|
||||||
|
sandbox:
|
||||||
|
condition: service_started
|
||||||
|
restart: always
|
||||||
|
environment:
|
||||||
|
# 前端外部可访问的地址,用于自动补全文件资源路径。例如 https:fastgpt.cn,不能填 localhost。这个值可以不填,不填则发给模型的图片会是一个相对路径,而不是全路径,模型可能伪造Host。
|
||||||
|
- FE_DOMAIN=
|
||||||
|
# root 密码,用户名为: root。如果需要修改 root 密码,直接修改这个环境变量,并重启即可。
|
||||||
|
- DEFAULT_ROOT_PSW=1234
|
||||||
|
# # AI Proxy 的地址,如果配了该地址,优先使用
|
||||||
|
# - AIPROXY_API_ENDPOINT=http://aiproxy:3000
|
||||||
|
# # AI Proxy 的 Admin Token,与 AI Proxy 中的环境变量 ADMIN_KEY
|
||||||
|
# - AIPROXY_API_TOKEN=aiproxy
|
||||||
|
# 模型中转地址(如果用了 AI Proxy,下面 2 个就不需要了,旧版 OneAPI 用户,使用下面的变量)
|
||||||
|
- # openai 基本地址,可用作中转。
|
||||||
|
- OPENAI_BASE_URL=https://dashscope.aliyuncs.com/compatible-mode/v1
|
||||||
|
- # OpenAI API Key
|
||||||
|
- CHAT_API_KEY=sk-8990fa15a34b464a805237cfe9561f11
|
||||||
|
# 数据库最大连接数
|
||||||
|
- DB_MAX_LINK=30
|
||||||
|
# 登录凭证密钥
|
||||||
|
- TOKEN_KEY=any
|
||||||
|
# root的密钥,常用于升级时候的初始化请求
|
||||||
|
- ROOT_KEY=root_key
|
||||||
|
# 文件阅读加密
|
||||||
|
- FILE_TOKEN_KEY=filetoken
|
||||||
|
# MongoDB 连接参数. 用户名myusername,密码mypassword。
|
||||||
|
- MONGODB_URI=mongodb://myusername:mypassword@mongo:27017/fastgpt?authSource=admin
|
||||||
|
# OceanBase 向量库连接参数
|
||||||
|
- OCEANBASE_URL=mysql://root%40tenantname:tenantpassword@ob:2881/test
|
||||||
|
# sandbox 地址
|
||||||
|
- SANDBOX_URL=http://sandbox:3000
|
||||||
|
# 日志等级: debug, info, warn, error
|
||||||
|
- LOG_LEVEL=info
|
||||||
|
- STORE_LOG_LEVEL=warn
|
||||||
|
# 工作流最大运行次数
|
||||||
|
- WORKFLOW_MAX_RUN_TIMES=1000
|
||||||
|
# 批量执行节点,最大输入长度
|
||||||
|
- WORKFLOW_MAX_LOOP_TIMES=100
|
||||||
|
# 自定义跨域,不配置时,默认都允许跨域(多个域名通过逗号分割)
|
||||||
|
- ALLOWED_ORIGINS=
|
||||||
|
# 是否开启IP限制,默认不开启
|
||||||
|
- USE_IP_LIMIT=false
|
||||||
|
volumes:
|
||||||
|
- ./config.json:/app/data/config.json
|
||||||
|
|
||||||
|
# AI Proxy
|
||||||
|
aiproxy:
|
||||||
|
image: ghcr.io/labring/aiproxy:v0.1.5
|
||||||
|
# image: registry.cn-hangzhou.aliyuncs.com/labring/aiproxy:v0.1.3 # 阿里云
|
||||||
|
container_name: aiproxy
|
||||||
|
restart: unless-stopped
|
||||||
|
depends_on:
|
||||||
|
aiproxy_pg:
|
||||||
|
condition: service_healthy
|
||||||
|
networks:
|
||||||
|
- fastgpt
|
||||||
|
environment:
|
||||||
|
# 对应 fastgpt 里的AIPROXY_API_TOKEN
|
||||||
|
- ADMIN_KEY=aiproxy
|
||||||
|
# 错误日志详情保存时间(小时)
|
||||||
|
- LOG_DETAIL_STORAGE_HOURS=1
|
||||||
|
# 数据库连接地址
|
||||||
|
- SQL_DSN=postgres://postgres:aiproxy@aiproxy_pg:5432/aiproxy
|
||||||
|
# 最大重试次数
|
||||||
|
- RETRY_TIMES=3
|
||||||
|
# 不需要计费
|
||||||
|
- BILLING_ENABLED=false
|
||||||
|
# 不需要严格检测模型
|
||||||
|
- DISABLE_MODEL_CONFIG=true
|
||||||
|
healthcheck:
|
||||||
|
test: ['CMD', 'curl', '-f', 'http://localhost:3000/api/status']
|
||||||
|
interval: 5s
|
||||||
|
timeout: 5s
|
||||||
|
retries: 10
|
||||||
|
aiproxy_pg:
|
||||||
|
image: pgvector/pgvector:0.8.0-pg15 # docker hub
|
||||||
|
# image: registry.cn-hangzhou.aliyuncs.com/fastgpt/pgvector:v0.8.0-pg15 # 阿里云
|
||||||
|
restart: unless-stopped
|
||||||
|
container_name: aiproxy_pg
|
||||||
|
volumes:
|
||||||
|
- ./aiproxy_pg:/var/lib/postgresql/data
|
||||||
|
networks:
|
||||||
|
- fastgpt
|
||||||
|
environment:
|
||||||
|
TZ: Asia/Shanghai
|
||||||
|
POSTGRES_USER: postgres
|
||||||
|
POSTGRES_DB: aiproxy
|
||||||
|
POSTGRES_PASSWORD: aiproxy
|
||||||
|
healthcheck:
|
||||||
|
test: ['CMD', 'pg_isready', '-U', 'postgres', '-d', 'aiproxy']
|
||||||
|
interval: 5s
|
||||||
|
timeout: 5s
|
||||||
|
retries: 10
|
||||||
|
networks:
|
||||||
|
fastgpt:
|
||||||
2
deploy/docker/docker-compose-oceanbase/init.sql
Normal file
2
deploy/docker/docker-compose-oceanbase/init.sql
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
ALTER SYSTEM SET ob_vector_memory_limit_percentage = 30;
|
||||||
|
|
||||||
@@ -85,15 +85,15 @@ services:
|
|||||||
# fastgpt
|
# fastgpt
|
||||||
sandbox:
|
sandbox:
|
||||||
container_name: sandbox
|
container_name: sandbox
|
||||||
image: ghcr.io/labring/fastgpt-sandbox:v4.9.3 # git
|
image: ghcr.io/labring/fastgpt-sandbox:v4.9.4 # git
|
||||||
# image: registry.cn-hangzhou.aliyuncs.com/fastgpt/fastgpt-sandbox:v4.9.3 # 阿里云
|
# image: registry.cn-hangzhou.aliyuncs.com/fastgpt/fastgpt-sandbox:v4.9.4 # 阿里云
|
||||||
networks:
|
networks:
|
||||||
- fastgpt
|
- fastgpt
|
||||||
restart: always
|
restart: always
|
||||||
fastgpt:
|
fastgpt:
|
||||||
container_name: fastgpt
|
container_name: fastgpt
|
||||||
image: ghcr.io/labring/fastgpt:v4.9.3 # git
|
image: ghcr.io/labring/fastgpt:v4.9.4 # git
|
||||||
# image: registry.cn-hangzhou.aliyuncs.com/fastgpt/fastgpt:v4.9.3 # 阿里云
|
# image: registry.cn-hangzhou.aliyuncs.com/fastgpt/fastgpt:v4.9.4 # 阿里云
|
||||||
ports:
|
ports:
|
||||||
- 3000:3000
|
- 3000:3000
|
||||||
networks:
|
networks:
|
||||||
@@ -142,6 +142,8 @@ services:
|
|||||||
- ALLOWED_ORIGINS=
|
- ALLOWED_ORIGINS=
|
||||||
# 是否开启IP限制,默认不开启
|
# 是否开启IP限制,默认不开启
|
||||||
- USE_IP_LIMIT=false
|
- USE_IP_LIMIT=false
|
||||||
|
# 对话文件过期天数
|
||||||
|
- CHAT_FILE_EXPIRE_TIME=7
|
||||||
volumes:
|
volumes:
|
||||||
- ./config.json:/app/data/config.json
|
- ./config.json:/app/data/config.json
|
||||||
|
|
||||||
|
|||||||
@@ -66,15 +66,15 @@ services:
|
|||||||
|
|
||||||
sandbox:
|
sandbox:
|
||||||
container_name: sandbox
|
container_name: sandbox
|
||||||
image: ghcr.io/labring/fastgpt-sandbox:v4.9.3 # git
|
image: ghcr.io/labring/fastgpt-sandbox:v4.9.4 # git
|
||||||
# image: registry.cn-hangzhou.aliyuncs.com/fastgpt/fastgpt-sandbox:v4.9.3 # 阿里云
|
# image: registry.cn-hangzhou.aliyuncs.com/fastgpt/fastgpt-sandbox:v4.9.4 # 阿里云
|
||||||
networks:
|
networks:
|
||||||
- fastgpt
|
- fastgpt
|
||||||
restart: always
|
restart: always
|
||||||
fastgpt:
|
fastgpt:
|
||||||
container_name: fastgpt
|
container_name: fastgpt
|
||||||
image: ghcr.io/labring/fastgpt:v4.9.3 # git
|
image: ghcr.io/labring/fastgpt:v4.9.4 # git
|
||||||
# image: registry.cn-hangzhou.aliyuncs.com/fastgpt/fastgpt:v4.9.3 # 阿里云
|
# image: registry.cn-hangzhou.aliyuncs.com/fastgpt/fastgpt:v4.9.4 # 阿里云
|
||||||
ports:
|
ports:
|
||||||
- 3000:3000
|
- 3000:3000
|
||||||
networks:
|
networks:
|
||||||
@@ -123,6 +123,8 @@ services:
|
|||||||
- ALLOWED_ORIGINS=
|
- ALLOWED_ORIGINS=
|
||||||
# 是否开启IP限制,默认不开启
|
# 是否开启IP限制,默认不开启
|
||||||
- USE_IP_LIMIT=false
|
- USE_IP_LIMIT=false
|
||||||
|
# 对话文件过期天数
|
||||||
|
- CHAT_FILE_EXPIRE_TIME=7
|
||||||
volumes:
|
volumes:
|
||||||
- ./config.json:/app/data/config.json
|
- ./config.json:/app/data/config.json
|
||||||
|
|
||||||
|
|||||||
@@ -135,6 +135,9 @@ curl -O https://raw.githubusercontent.com/labring/FastGPT/main/projects/app/data
|
|||||||
|
|
||||||
# pgvector 版本(测试推荐,简单快捷)
|
# pgvector 版本(测试推荐,简单快捷)
|
||||||
curl -o docker-compose.yml https://raw.githubusercontent.com/labring/FastGPT/main/deploy/docker/docker-compose-pgvector.yml
|
curl -o docker-compose.yml https://raw.githubusercontent.com/labring/FastGPT/main/deploy/docker/docker-compose-pgvector.yml
|
||||||
|
# oceanbase 版本(需要将init.sql和docker-compose.yml放在同一个文件夹,方便挂载)
|
||||||
|
# curl -o docker-compose.yml https://raw.githubusercontent.com/labring/FastGPT/main/deploy/docker/docker-compose-oceanbase/docker-compose.yml
|
||||||
|
# curl -o init.sql https://raw.githubusercontent.com/labring/FastGPT/main/deploy/docker/docker-compose-oceanbase/init.sql
|
||||||
# milvus 版本
|
# milvus 版本
|
||||||
# curl -o docker-compose.yml https://raw.githubusercontent.com/labring/FastGPT/main/deploy/docker/docker-compose-milvus.yml
|
# curl -o docker-compose.yml https://raw.githubusercontent.com/labring/FastGPT/main/deploy/docker/docker-compose-milvus.yml
|
||||||
# zilliz 版本
|
# zilliz 版本
|
||||||
@@ -151,6 +154,13 @@ curl -o docker-compose.yml https://raw.githubusercontent.com/labring/FastGPT/mai
|
|||||||
|
|
||||||
无需操作
|
无需操作
|
||||||
|
|
||||||
|
{{< /markdownify >}}
|
||||||
|
{{< /tab >}}
|
||||||
|
{{< tab tabName="Oceanbase版本" >}}
|
||||||
|
{{< markdownify >}}
|
||||||
|
|
||||||
|
无需操作
|
||||||
|
|
||||||
{{< /markdownify >}}
|
{{< /markdownify >}}
|
||||||
{{< /tab >}}
|
{{< /tab >}}
|
||||||
{{< tab tabName="Milvus版本" >}}
|
{{< tab tabName="Milvus版本" >}}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
---
|
---
|
||||||
title: 'V4.9.4(进行中)'
|
title: 'V4.9.4'
|
||||||
description: 'FastGPT V4.9.4 更新说明'
|
description: 'FastGPT V4.9.4 更新说明'
|
||||||
icon: 'upgrade'
|
icon: 'upgrade'
|
||||||
draft: false
|
draft: false
|
||||||
@@ -11,7 +11,7 @@ weight: 796
|
|||||||
|
|
||||||
### 1. 做好数据备份
|
### 1. 做好数据备份
|
||||||
|
|
||||||
### 1. 安装 Redis
|
### 2. 安装 Redis
|
||||||
|
|
||||||
* docker 部署的用户,参考最新的 `docker-compose.yml` 文件增加 Redis 配置。增加一个 redis 容器,并配置`fastgpt`,`fastgpt-pro`的环境变量,增加 `REDIS_URL` 环境变量。
|
* docker 部署的用户,参考最新的 `docker-compose.yml` 文件增加 Redis 配置。增加一个 redis 容器,并配置`fastgpt`,`fastgpt-pro`的环境变量,增加 `REDIS_URL` 环境变量。
|
||||||
* Sealos 部署的用户,在数据库里新建一个`redis`数据库,并复制`内网地址的 connection` 作为 `redis` 的链接串。然后配置`fastgpt`,`fastgpt-pro`的环境变量,增加 `REDIS_URL` 环境变量。
|
* Sealos 部署的用户,在数据库里新建一个`redis`数据库,并复制`内网地址的 connection` 作为 `redis` 的链接串。然后配置`fastgpt`,`fastgpt-pro`的环境变量,增加 `REDIS_URL` 环境变量。
|
||||||
@@ -20,14 +20,14 @@ weight: 796
|
|||||||
| --- | --- | --- |
|
| --- | --- | --- |
|
||||||
|  |  |  |
|
|  |  |  |
|
||||||
|
|
||||||
### 2. 更新镜像 tag
|
### 3. 更新镜像 tag
|
||||||
|
|
||||||
- 更新 FastGPT 镜像 tag: v4.9.4-alpha
|
- 更新 FastGPT 镜像 tag: v4.9.4
|
||||||
- 更新 FastGPT 商业版镜像 tag: v4.9.4-alpha
|
- 更新 FastGPT 商业版镜像 tag: v4.9.4
|
||||||
- Sandbox 无需更新
|
- Sandbox 无需更新
|
||||||
- AIProxy 无需更新
|
- AIProxy 无需更新
|
||||||
|
|
||||||
### 3. 执行升级脚本
|
### 4. 执行升级脚本
|
||||||
|
|
||||||
该脚本仅需商业版用户执行。
|
该脚本仅需商业版用户执行。
|
||||||
|
|
||||||
@@ -49,8 +49,8 @@ curl --location --request POST 'https://{{host}}/api/admin/initv494' \
|
|||||||
2. SMTP 发送邮件插件
|
2. SMTP 发送邮件插件
|
||||||
3. BullMQ 消息队列。
|
3. BullMQ 消息队列。
|
||||||
4. 利用 redis 进行部分数据缓存。
|
4. 利用 redis 进行部分数据缓存。
|
||||||
5. 站点同步支持配置训练参数。
|
5. 站点同步支持配置训练参数和增量同步。
|
||||||
6. AI 对话/工具调用,增加返回模型 finish_reason 字段。
|
6. AI 对话/工具调用,增加返回模型 finish_reason 字段,便于追踪模型输出中断原因。
|
||||||
7. 移动端语音输入交互调整
|
7. 移动端语音输入交互调整
|
||||||
|
|
||||||
## ⚙️ 优化
|
## ⚙️ 优化
|
||||||
|
|||||||
28
docSite/content/zh-cn/docs/development/upgrading/495.md
Normal file
28
docSite/content/zh-cn/docs/development/upgrading/495.md
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
---
|
||||||
|
title: 'V4.9.5(进行中)'
|
||||||
|
description: 'FastGPT V4.9.5 更新说明'
|
||||||
|
icon: 'upgrade'
|
||||||
|
draft: false
|
||||||
|
toc: true
|
||||||
|
weight: 795
|
||||||
|
---
|
||||||
|
|
||||||
|
|
||||||
|
## 🚀 新增内容
|
||||||
|
|
||||||
|
1. 团队成员权限细分,可分别控制是否可创建在根目录应用/知识库以及 API Key
|
||||||
|
2. 支持交互节点在嵌套工作流中使用。
|
||||||
|
3. 团队成员操作日志。
|
||||||
|
|
||||||
|
## ⚙️ 优化
|
||||||
|
|
||||||
|
1. 繁体中文翻译。
|
||||||
|
|
||||||
|
|
||||||
|
## 🐛 修复
|
||||||
|
|
||||||
|
1. password 检测规则错误。
|
||||||
|
2. 分享链接无法隐藏知识库检索结果。
|
||||||
|
3. IOS 低版本正则兼容问题。
|
||||||
|
4. 修复问答提取队列错误后,计数器未清零问题,导致问答提取队列失效。
|
||||||
|
5. Debug 模式交互节点下一步可能造成死循环。
|
||||||
12
package.json
12
package.json
@@ -12,27 +12,29 @@
|
|||||||
"previewIcon": "node ./scripts/icon/index.js",
|
"previewIcon": "node ./scripts/icon/index.js",
|
||||||
"api:gen": "tsc ./scripts/openapi/index.ts && node ./scripts/openapi/index.js && npx @redocly/cli build-docs ./scripts/openapi/openapi.json -o ./projects/app/public/openapi/index.html",
|
"api:gen": "tsc ./scripts/openapi/index.ts && node ./scripts/openapi/index.js && npx @redocly/cli build-docs ./scripts/openapi/openapi.json -o ./projects/app/public/openapi/index.html",
|
||||||
"create:i18n": "node ./scripts/i18n/index.js",
|
"create:i18n": "node ./scripts/i18n/index.js",
|
||||||
"test": "vitest run --exclude 'test/cases/spec'",
|
"test": "vitest run",
|
||||||
"test:all": "vitest run",
|
|
||||||
"test:workflow": "vitest run workflow"
|
"test:workflow": "vitest run workflow"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@chakra-ui/cli": "^2.4.1",
|
"@chakra-ui/cli": "^2.4.1",
|
||||||
"@vitest/coverage-v8": "^3.0.2",
|
"@vitest/coverage-v8": "^3.0.9",
|
||||||
"husky": "^8.0.3",
|
"husky": "^8.0.3",
|
||||||
"i18next": "23.16.8",
|
"i18next": "23.16.8",
|
||||||
"lint-staged": "^13.3.0",
|
"lint-staged": "^13.3.0",
|
||||||
"next-i18next": "15.4.2",
|
"next-i18next": "15.4.2",
|
||||||
"prettier": "3.2.4",
|
"prettier": "3.2.4",
|
||||||
"react-i18next": "14.1.2",
|
"react-i18next": "14.1.2",
|
||||||
"vitest": "^3.0.2",
|
"vitest": "^3.0.9",
|
||||||
"vitest-mongodb": "^1.0.1",
|
"mongodb-memory-server": "^10.1.4",
|
||||||
"zhlint": "^0.7.4"
|
"zhlint": "^0.7.4"
|
||||||
},
|
},
|
||||||
"lint-staged": {
|
"lint-staged": {
|
||||||
"./**/**/*.{ts,tsx,scss}": "npm run format-code",
|
"./**/**/*.{ts,tsx,scss}": "npm run format-code",
|
||||||
"./docSite/**/**/*.md": "npm run format-doc"
|
"./docSite/**/**/*.md": "npm run format-doc"
|
||||||
},
|
},
|
||||||
|
"resolutions": {
|
||||||
|
"mdast-util-gfm-autolink-literal": "2.0.0"
|
||||||
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=18.16.0",
|
"node": ">=18.16.0",
|
||||||
"pnpm": ">=9.0.0"
|
"pnpm": ">=9.0.0"
|
||||||
|
|||||||
@@ -77,6 +77,13 @@ export const getHistoryPreview = (
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const filterModuleTypeList: any[] = [
|
||||||
|
FlowNodeTypeEnum.pluginModule,
|
||||||
|
FlowNodeTypeEnum.datasetSearchNode,
|
||||||
|
FlowNodeTypeEnum.tools,
|
||||||
|
FlowNodeTypeEnum.pluginOutput
|
||||||
|
];
|
||||||
|
|
||||||
export const filterPublicNodeResponseData = ({
|
export const filterPublicNodeResponseData = ({
|
||||||
flowResponses = [],
|
flowResponses = [],
|
||||||
responseDetail = false
|
responseDetail = false
|
||||||
@@ -87,12 +94,6 @@ export const filterPublicNodeResponseData = ({
|
|||||||
const filedList = responseDetail
|
const filedList = responseDetail
|
||||||
? ['quoteList', 'moduleType', 'pluginOutput', 'runningTime']
|
? ['quoteList', 'moduleType', 'pluginOutput', 'runningTime']
|
||||||
: ['moduleType', 'pluginOutput', 'runningTime'];
|
: ['moduleType', 'pluginOutput', 'runningTime'];
|
||||||
const filterModuleTypeList: any[] = [
|
|
||||||
FlowNodeTypeEnum.pluginModule,
|
|
||||||
FlowNodeTypeEnum.datasetSearchNode,
|
|
||||||
FlowNodeTypeEnum.tools,
|
|
||||||
FlowNodeTypeEnum.pluginOutput
|
|
||||||
];
|
|
||||||
|
|
||||||
return flowResponses
|
return flowResponses
|
||||||
.filter((item) => filterModuleTypeList.includes(item.moduleType))
|
.filter((item) => filterModuleTypeList.includes(item.moduleType))
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ import { WorkflowResponseType } from '../../../../service/core/workflow/dispatch
|
|||||||
import { AiChatQuoteRoleType } from '../template/system/aiChat/type';
|
import { AiChatQuoteRoleType } from '../template/system/aiChat/type';
|
||||||
import { LafAccountType, OpenaiAccountType } from '../../../support/user/team/type';
|
import { LafAccountType, OpenaiAccountType } from '../../../support/user/team/type';
|
||||||
import { CompletionFinishReason } from '../../ai/type';
|
import { CompletionFinishReason } from '../../ai/type';
|
||||||
|
import { WorkflowInteractiveResponseType } from '../template/system/interactive/type';
|
||||||
export type ExternalProviderType = {
|
export type ExternalProviderType = {
|
||||||
openaiAccount?: OpenaiAccountType;
|
openaiAccount?: OpenaiAccountType;
|
||||||
externalWorkflowVariables?: Record<string, string>;
|
externalWorkflowVariables?: Record<string, string>;
|
||||||
@@ -55,12 +55,14 @@ export type ChatDispatchProps = {
|
|||||||
variables: Record<string, any>; // global variable
|
variables: Record<string, any>; // global variable
|
||||||
query: UserChatItemValueItemType[]; // trigger query
|
query: UserChatItemValueItemType[]; // trigger query
|
||||||
chatConfig: AppSchema['chatConfig'];
|
chatConfig: AppSchema['chatConfig'];
|
||||||
|
lastInteractive?: WorkflowInteractiveResponseType; // last interactive response
|
||||||
stream: boolean;
|
stream: boolean;
|
||||||
maxRunTimes: number;
|
maxRunTimes: number;
|
||||||
isToolCall?: boolean;
|
isToolCall?: boolean;
|
||||||
workflowStreamResponse?: WorkflowResponseType;
|
workflowStreamResponse?: WorkflowResponseType;
|
||||||
workflowDispatchDeep?: number;
|
workflowDispatchDeep?: number;
|
||||||
version?: 'v1' | 'v2';
|
version?: 'v1' | 'v2';
|
||||||
|
responseDetail?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type ModuleDispatchProps<T> = ChatDispatchProps & {
|
export type ModuleDispatchProps<T> = ChatDispatchProps & {
|
||||||
|
|||||||
@@ -10,7 +10,19 @@ import { FlowNodeOutputItemType, ReferenceValueType } from '../type/io';
|
|||||||
import { ChatItemType, NodeOutputItemType } from '../../../core/chat/type';
|
import { ChatItemType, NodeOutputItemType } from '../../../core/chat/type';
|
||||||
import { ChatItemValueTypeEnum, ChatRoleEnum } from '../../../core/chat/constants';
|
import { ChatItemValueTypeEnum, ChatRoleEnum } from '../../../core/chat/constants';
|
||||||
import { replaceVariable, valToStr } from '../../../common/string/tools';
|
import { replaceVariable, valToStr } from '../../../common/string/tools';
|
||||||
|
import {
|
||||||
|
InteractiveNodeResponseType,
|
||||||
|
WorkflowInteractiveResponseType
|
||||||
|
} from '../template/system/interactive/type';
|
||||||
|
|
||||||
|
export const extractDeepestInteractive = (
|
||||||
|
interactive: WorkflowInteractiveResponseType
|
||||||
|
): WorkflowInteractiveResponseType => {
|
||||||
|
if (interactive?.type === 'childrenInteractive' && interactive.params?.childrenResponse) {
|
||||||
|
return extractDeepestInteractive(interactive.params.childrenResponse);
|
||||||
|
}
|
||||||
|
return interactive;
|
||||||
|
};
|
||||||
export const getMaxHistoryLimitFromNodes = (nodes: StoreNodeItemType[]): number => {
|
export const getMaxHistoryLimitFromNodes = (nodes: StoreNodeItemType[]): number => {
|
||||||
let limit = 10;
|
let limit = 10;
|
||||||
nodes.forEach((node) => {
|
nodes.forEach((node) => {
|
||||||
@@ -34,7 +46,9 @@ export const getMaxHistoryLimitFromNodes = (nodes: StoreNodeItemType[]): number
|
|||||||
1. Get the interactive data
|
1. Get the interactive data
|
||||||
2. Check that the workflow starts at the interaction node
|
2. Check that the workflow starts at the interaction node
|
||||||
*/
|
*/
|
||||||
export const getLastInteractiveValue = (histories: ChatItemType[]) => {
|
export const getLastInteractiveValue = (
|
||||||
|
histories: ChatItemType[]
|
||||||
|
): WorkflowInteractiveResponseType | undefined => {
|
||||||
const lastAIMessage = [...histories].reverse().find((item) => item.obj === ChatRoleEnum.AI);
|
const lastAIMessage = [...histories].reverse().find((item) => item.obj === ChatRoleEnum.AI);
|
||||||
|
|
||||||
if (lastAIMessage) {
|
if (lastAIMessage) {
|
||||||
@@ -45,7 +59,11 @@ export const getLastInteractiveValue = (histories: ChatItemType[]) => {
|
|||||||
lastValue.type !== ChatItemValueTypeEnum.interactive ||
|
lastValue.type !== ChatItemValueTypeEnum.interactive ||
|
||||||
!lastValue.interactive
|
!lastValue.interactive
|
||||||
) {
|
) {
|
||||||
return null;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lastValue.interactive.type === 'childrenInteractive') {
|
||||||
|
return lastValue.interactive;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check is user select
|
// Check is user select
|
||||||
@@ -62,38 +80,29 @@ export const getLastInteractiveValue = (histories: ChatItemType[]) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const initWorkflowEdgeStatus = (
|
export const initWorkflowEdgeStatus = (
|
||||||
edges: StoreEdgeItemType[] | RuntimeEdgeItemType[],
|
edges: StoreEdgeItemType[],
|
||||||
histories?: ChatItemType[]
|
lastInteractive?: WorkflowInteractiveResponseType
|
||||||
): RuntimeEdgeItemType[] => {
|
): RuntimeEdgeItemType[] => {
|
||||||
// If there is a history, use the last interactive value
|
if (lastInteractive) {
|
||||||
if (histories && histories.length > 0) {
|
const memoryEdges = lastInteractive.memoryEdges || [];
|
||||||
const memoryEdges = getLastInteractiveValue(histories)?.memoryEdges;
|
|
||||||
|
|
||||||
if (memoryEdges && memoryEdges.length > 0) {
|
if (memoryEdges && memoryEdges.length > 0) {
|
||||||
return memoryEdges;
|
return memoryEdges;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return edges?.map((edge) => ({ ...edge, status: 'waiting' })) || [];
|
||||||
edges?.map((edge) => ({
|
|
||||||
...edge,
|
|
||||||
status: 'waiting'
|
|
||||||
})) || []
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getWorkflowEntryNodeIds = (
|
export const getWorkflowEntryNodeIds = (
|
||||||
nodes: (StoreNodeItemType | RuntimeNodeItemType)[],
|
nodes: (StoreNodeItemType | RuntimeNodeItemType)[],
|
||||||
histories?: ChatItemType[]
|
lastInteractive?: WorkflowInteractiveResponseType
|
||||||
) => {
|
) => {
|
||||||
// If there is a history, use the last interactive entry node
|
if (lastInteractive) {
|
||||||
if (histories && histories.length > 0) {
|
const entryNodeIds = lastInteractive.entryNodeIds || [];
|
||||||
const entryNodeIds = getLastInteractiveValue(histories)?.entryNodeIds;
|
|
||||||
|
|
||||||
if (Array.isArray(entryNodeIds) && entryNodeIds.length > 0) {
|
if (Array.isArray(entryNodeIds) && entryNodeIds.length > 0) {
|
||||||
return entryNodeIds;
|
return entryNodeIds;
|
||||||
}
|
}
|
||||||
@@ -396,10 +405,10 @@ export const textAdaptGptResponse = ({
|
|||||||
|
|
||||||
/* Update runtimeNode's outputs with interactive data from history */
|
/* Update runtimeNode's outputs with interactive data from history */
|
||||||
export function rewriteNodeOutputByHistories(
|
export function rewriteNodeOutputByHistories(
|
||||||
histories: ChatItemType[],
|
runtimeNodes: RuntimeNodeItemType[],
|
||||||
runtimeNodes: RuntimeNodeItemType[]
|
lastInteractive?: InteractiveNodeResponseType
|
||||||
) {
|
) {
|
||||||
const interactive = getLastInteractiveValue(histories);
|
const interactive = lastInteractive;
|
||||||
if (!interactive?.nodeOutputs) {
|
if (!interactive?.nodeOutputs) {
|
||||||
return runtimeNodes;
|
return runtimeNodes;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import type { NodeOutputItemType } from '../../../../chat/type';
|
import type { NodeOutputItemType } from '../../../../chat/type';
|
||||||
import type { FlowNodeOutputItemType } from '../../../type/io';
|
import type { FlowNodeOutputItemType } from '../../../type/io';
|
||||||
import type { RuntimeEdgeItemType } from '../../../runtime/type';
|
|
||||||
import { FlowNodeInputTypeEnum } from 'core/workflow/node/constant';
|
import { FlowNodeInputTypeEnum } from 'core/workflow/node/constant';
|
||||||
import { WorkflowIOValueTypeEnum } from 'core/workflow/constants';
|
import { WorkflowIOValueTypeEnum } from 'core/workflow/constants';
|
||||||
import type { ChatCompletionMessageParam } from '../../../../ai/type';
|
import type { ChatCompletionMessageParam } from '../../../../ai/type';
|
||||||
@@ -9,7 +8,6 @@ type InteractiveBasicType = {
|
|||||||
entryNodeIds: string[];
|
entryNodeIds: string[];
|
||||||
memoryEdges: RuntimeEdgeItemType[];
|
memoryEdges: RuntimeEdgeItemType[];
|
||||||
nodeOutputs: NodeOutputItemType[];
|
nodeOutputs: NodeOutputItemType[];
|
||||||
|
|
||||||
toolParams?: {
|
toolParams?: {
|
||||||
entryNodeIds: string[]; // 记录工具中,交互节点的 Id,而不是起始工作流的入口
|
entryNodeIds: string[]; // 记录工具中,交互节点的 Id,而不是起始工作流的入口
|
||||||
memoryMessages: ChatCompletionMessageParam[]; // 这轮工具中,产生的新的 messages
|
memoryMessages: ChatCompletionMessageParam[]; // 这轮工具中,产生的新的 messages
|
||||||
@@ -23,6 +21,13 @@ type InteractiveNodeType = {
|
|||||||
nodeOutputs?: NodeOutputItemType[];
|
nodeOutputs?: NodeOutputItemType[];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
type ChildrenInteractive = InteractiveNodeType & {
|
||||||
|
type: 'childrenInteractive';
|
||||||
|
params: {
|
||||||
|
childrenResponse?: WorkflowInteractiveResponseType;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
export type UserSelectOptionItemType = {
|
export type UserSelectOptionItemType = {
|
||||||
key: string;
|
key: string;
|
||||||
value: string;
|
value: string;
|
||||||
@@ -62,5 +67,9 @@ type UserInputInteractive = InteractiveNodeType & {
|
|||||||
submitted?: boolean;
|
submitted?: boolean;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
export type InteractiveNodeResponseType = UserSelectInteractive | UserInputInteractive;
|
|
||||||
|
export type InteractiveNodeResponseType =
|
||||||
|
| UserSelectInteractive
|
||||||
|
| UserInputInteractive
|
||||||
|
| ChildrenInteractive;
|
||||||
export type WorkflowInteractiveResponseType = InteractiveBasicType & InteractiveNodeResponseType;
|
export type WorkflowInteractiveResponseType = InteractiveBasicType & InteractiveNodeResponseType;
|
||||||
|
|||||||
14
packages/global/support/operationLog/constants.ts
Normal file
14
packages/global/support/operationLog/constants.ts
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
export enum OperationLogEventEnum {
|
||||||
|
LOGIN = 'LOGIN',
|
||||||
|
CREATE_INVITATION_LINK = 'CREATE_INVITATION_LINK',
|
||||||
|
JOIN_TEAM = 'JOIN_TEAM',
|
||||||
|
CHANGE_MEMBER_NAME = 'CHANGE_MEMBER_NAME',
|
||||||
|
KICK_OUT_TEAM = 'KICK_OUT_TEAM',
|
||||||
|
CREATE_DEPARTMENT = 'CREATE_DEPARTMENT',
|
||||||
|
CHANGE_DEPARTMENT = 'CHANGE_DEPARTMENT',
|
||||||
|
DELETE_DEPARTMENT = 'DELETE_DEPARTMENT',
|
||||||
|
RELOCATE_DEPARTMENT = 'RELOCATE_DEPARTMENT',
|
||||||
|
CREATE_GROUP = 'CREATE_GROUP',
|
||||||
|
DELETE_GROUP = 'DELETE_GROUP',
|
||||||
|
ASSIGN_PERMISSION = 'ASSIGN_PERMISSION'
|
||||||
|
}
|
||||||
19
packages/global/support/operationLog/type.d.ts
vendored
Normal file
19
packages/global/support/operationLog/type.d.ts
vendored
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
import { SourceMemberType } from '../user/type';
|
||||||
|
import { OperationLogEventEnum } from './constants';
|
||||||
|
|
||||||
|
export type OperationLogSchema = {
|
||||||
|
_id: string;
|
||||||
|
tmbId: string;
|
||||||
|
teamId: string;
|
||||||
|
timestamp: Date;
|
||||||
|
event: `${OperationLogEventEnum}`;
|
||||||
|
metadata?: Record<string, string>;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type OperationListItemType = {
|
||||||
|
_id: string;
|
||||||
|
sourceMember: SourceMemberType;
|
||||||
|
event: `${OperationLogEventEnum}`;
|
||||||
|
timestamp: Date;
|
||||||
|
metadata: Record<string, string>;
|
||||||
|
};
|
||||||
@@ -13,12 +13,15 @@ export type CollaboratorItemType = {
|
|||||||
orgId: string;
|
orgId: string;
|
||||||
}>;
|
}>;
|
||||||
|
|
||||||
export type UpdateClbPermissionProps = {
|
export type UpdateClbPermissionProps<addOnly = false> = {
|
||||||
members?: string[];
|
members?: string[];
|
||||||
groups?: string[];
|
groups?: string[];
|
||||||
orgs?: string[];
|
orgs?: string[];
|
||||||
permission: PermissionValueType;
|
} & (addOnly extends true
|
||||||
};
|
? {}
|
||||||
|
: {
|
||||||
|
permission: PermissionValueType;
|
||||||
|
});
|
||||||
|
|
||||||
export type DeletePermissionQuery = RequireOnlyOne<{
|
export type DeletePermissionQuery = RequireOnlyOne<{
|
||||||
tmbId?: string;
|
tmbId?: string;
|
||||||
|
|||||||
@@ -5,15 +5,16 @@ export type PerConstructPros = {
|
|||||||
per?: PermissionValueType;
|
per?: PermissionValueType;
|
||||||
isOwner?: boolean;
|
isOwner?: boolean;
|
||||||
permissionList?: PermissionListType;
|
permissionList?: PermissionListType;
|
||||||
|
childUpdatePermissionCallback?: () => void;
|
||||||
};
|
};
|
||||||
|
|
||||||
// the Permission helper class
|
// the Permission helper class
|
||||||
export class Permission {
|
export class Permission {
|
||||||
value: PermissionValueType;
|
value: PermissionValueType;
|
||||||
isOwner: boolean;
|
isOwner: boolean = false;
|
||||||
hasManagePer: boolean;
|
hasManagePer: boolean = false;
|
||||||
hasWritePer: boolean;
|
hasWritePer: boolean = false;
|
||||||
hasReadPer: boolean;
|
hasReadPer: boolean = false;
|
||||||
_permissionList: PermissionListType;
|
_permissionList: PermissionListType;
|
||||||
|
|
||||||
constructor(props?: PerConstructPros) {
|
constructor(props?: PerConstructPros) {
|
||||||
@@ -24,11 +25,8 @@ export class Permission {
|
|||||||
this.value = per;
|
this.value = per;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.isOwner = isOwner;
|
|
||||||
this._permissionList = permissionList;
|
this._permissionList = permissionList;
|
||||||
this.hasManagePer = this.checkPer(this._permissionList['manage'].value);
|
this.updatePermissions();
|
||||||
this.hasWritePer = this.checkPer(this._permissionList['write'].value);
|
|
||||||
this.hasReadPer = this.checkPer(this._permissionList['read'].value);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// add permission(s)
|
// add permission(s)
|
||||||
@@ -68,10 +66,21 @@ export class Permission {
|
|||||||
return (this.value & perm) === perm;
|
return (this.value & perm) === perm;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private updatePermissionCallback?: () => void;
|
||||||
|
setUpdatePermissionCallback(callback: () => void) {
|
||||||
|
callback();
|
||||||
|
this.updatePermissionCallback = callback;
|
||||||
|
}
|
||||||
|
|
||||||
private updatePermissions() {
|
private updatePermissions() {
|
||||||
this.isOwner = this.value === OwnerPermissionVal;
|
this.isOwner = this.value === OwnerPermissionVal;
|
||||||
this.hasManagePer = this.checkPer(this._permissionList['manage'].value);
|
this.hasManagePer = this.checkPer(this._permissionList['manage'].value);
|
||||||
this.hasWritePer = this.checkPer(this._permissionList['write'].value);
|
this.hasWritePer = this.checkPer(this._permissionList['write'].value);
|
||||||
this.hasReadPer = this.checkPer(this._permissionList['read'].value);
|
this.hasReadPer = this.checkPer(this._permissionList['read'].value);
|
||||||
|
this.updatePermissionCallback?.();
|
||||||
|
}
|
||||||
|
|
||||||
|
toBinary() {
|
||||||
|
return this.value.toString(2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,23 +17,23 @@ type GroupMemberSchemaType = {
|
|||||||
role: `${GroupMemberRole}`;
|
role: `${GroupMemberRole}`;
|
||||||
};
|
};
|
||||||
|
|
||||||
type MemberGroupListItemType<T extends boolean | undefined> = MemberGroupSchemaType & {
|
type MemberGroupListItemType<WithMembers extends boolean | undefined> = MemberGroupSchemaType & {
|
||||||
members: T extends true
|
members: WithMembers extends true
|
||||||
? {
|
? {
|
||||||
tmbId: string;
|
tmbId: string;
|
||||||
name: string;
|
name: string;
|
||||||
avatar: string;
|
avatar: string;
|
||||||
}[]
|
}[]
|
||||||
: undefined;
|
: undefined;
|
||||||
count: T extends true ? number : undefined;
|
count: WithMembers extends true ? number : undefined;
|
||||||
owner?: T extends true
|
owner?: WithMembers extends true
|
||||||
? {
|
? {
|
||||||
tmbId: string;
|
tmbId: string;
|
||||||
name: string;
|
name: string;
|
||||||
avatar: string;
|
avatar: string;
|
||||||
}
|
}
|
||||||
: undefined;
|
: undefined;
|
||||||
permission: T extends true ? Permission : undefined;
|
permission: WithMembers extends true ? Permission : undefined;
|
||||||
};
|
};
|
||||||
|
|
||||||
type GroupMemberItemType = {
|
type GroupMemberItemType = {
|
||||||
|
|||||||
@@ -1,22 +1,50 @@
|
|||||||
import { PermissionKeyEnum } from '../constant';
|
import { PermissionKeyEnum } from '../constant';
|
||||||
import { PermissionListType } from '../type';
|
import { PermissionListType } from '../type';
|
||||||
import { PermissionList } from '../constant';
|
import { PermissionList } from '../constant';
|
||||||
export const TeamPermissionList: PermissionListType = {
|
import { i18nT } from '../../../../web/i18n/utils';
|
||||||
|
export enum TeamPermissionKeyEnum {
|
||||||
|
appCreate = 'appCreate',
|
||||||
|
datasetCreate = 'datasetCreate',
|
||||||
|
apikeyCreate = 'apikeyCreate'
|
||||||
|
}
|
||||||
|
|
||||||
|
export const TeamPermissionList: PermissionListType<TeamPermissionKeyEnum> = {
|
||||||
[PermissionKeyEnum.read]: {
|
[PermissionKeyEnum.read]: {
|
||||||
...PermissionList[PermissionKeyEnum.read],
|
...PermissionList[PermissionKeyEnum.read],
|
||||||
value: 0b100
|
value: 0b000100
|
||||||
},
|
},
|
||||||
[PermissionKeyEnum.write]: {
|
[PermissionKeyEnum.write]: {
|
||||||
...PermissionList[PermissionKeyEnum.write],
|
...PermissionList[PermissionKeyEnum.write],
|
||||||
value: 0b010
|
value: 0b000010
|
||||||
},
|
},
|
||||||
[PermissionKeyEnum.manage]: {
|
[PermissionKeyEnum.manage]: {
|
||||||
...PermissionList[PermissionKeyEnum.manage],
|
...PermissionList[PermissionKeyEnum.manage],
|
||||||
value: 0b001
|
value: 0b000001
|
||||||
|
},
|
||||||
|
[TeamPermissionKeyEnum.appCreate]: {
|
||||||
|
checkBoxType: 'multiple',
|
||||||
|
description: '',
|
||||||
|
name: i18nT('account_team:permission_appCreate'),
|
||||||
|
value: 0b001000
|
||||||
|
},
|
||||||
|
[TeamPermissionKeyEnum.datasetCreate]: {
|
||||||
|
checkBoxType: 'multiple',
|
||||||
|
description: '',
|
||||||
|
name: i18nT('account_team:permission_datasetCreate'),
|
||||||
|
value: 0b010000
|
||||||
|
},
|
||||||
|
[TeamPermissionKeyEnum.apikeyCreate]: {
|
||||||
|
checkBoxType: 'multiple',
|
||||||
|
description: '',
|
||||||
|
name: i18nT('account_team:permission_apikeyCreate'),
|
||||||
|
value: 0b100000
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
export const TeamReadPermissionVal = TeamPermissionList['read'].value;
|
export const TeamReadPermissionVal = TeamPermissionList['read'].value;
|
||||||
export const TeamWritePermissionVal = TeamPermissionList['write'].value;
|
export const TeamWritePermissionVal = TeamPermissionList['write'].value;
|
||||||
export const TeamManagePermissionVal = TeamPermissionList['manage'].value;
|
export const TeamManagePermissionVal = TeamPermissionList['manage'].value;
|
||||||
|
export const TeamAppCreatePermissionVal = TeamPermissionList['appCreate'].value;
|
||||||
|
export const TeamDatasetCreatePermissionVal = TeamPermissionList['datasetCreate'].value;
|
||||||
|
export const TeamApikeyCreatePermissionVal = TeamPermissionList['apikeyCreate'].value;
|
||||||
export const TeamDefaultPermissionVal = TeamReadPermissionVal;
|
export const TeamDefaultPermissionVal = TeamReadPermissionVal;
|
||||||
|
|||||||
@@ -1,7 +1,17 @@
|
|||||||
import { PerConstructPros, Permission } from '../controller';
|
import { PerConstructPros, Permission } from '../controller';
|
||||||
import { TeamDefaultPermissionVal, TeamPermissionList } from './constant';
|
import {
|
||||||
|
TeamApikeyCreatePermissionVal,
|
||||||
|
TeamAppCreatePermissionVal,
|
||||||
|
TeamDatasetCreatePermissionVal,
|
||||||
|
TeamDefaultPermissionVal,
|
||||||
|
TeamPermissionList
|
||||||
|
} from './constant';
|
||||||
|
|
||||||
export class TeamPermission extends Permission {
|
export class TeamPermission extends Permission {
|
||||||
|
hasAppCreatePer: boolean = false;
|
||||||
|
hasDatasetCreatePer: boolean = false;
|
||||||
|
hasApikeyCreatePer: boolean = false;
|
||||||
|
|
||||||
constructor(props?: PerConstructPros) {
|
constructor(props?: PerConstructPros) {
|
||||||
if (!props) {
|
if (!props) {
|
||||||
props = {
|
props = {
|
||||||
@@ -12,5 +22,11 @@ export class TeamPermission extends Permission {
|
|||||||
}
|
}
|
||||||
props.permissionList = TeamPermissionList;
|
props.permissionList = TeamPermissionList;
|
||||||
super(props);
|
super(props);
|
||||||
|
|
||||||
|
this.setUpdatePermissionCallback(() => {
|
||||||
|
this.hasAppCreatePer = this.checkPer(TeamAppCreatePermissionVal);
|
||||||
|
this.hasDatasetCreatePer = this.checkPer(TeamDatasetCreatePermissionVal);
|
||||||
|
this.hasApikeyCreatePer = this.checkPer(TeamApikeyCreatePermissionVal);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -69,7 +69,7 @@ const addCommonMiddleware = (schema: mongoose.Schema) => {
|
|||||||
|
|
||||||
export const getMongoModel = <T>(name: string, schema: mongoose.Schema) => {
|
export const getMongoModel = <T>(name: string, schema: mongoose.Schema) => {
|
||||||
if (connectionMongo.models[name]) return connectionMongo.models[name] as Model<T>;
|
if (connectionMongo.models[name]) return connectionMongo.models[name] as Model<T>;
|
||||||
console.log('Load model======', name);
|
if (process.env.NODE_ENV !== 'test') console.log('Load model======', name);
|
||||||
addCommonMiddleware(schema);
|
addCommonMiddleware(schema);
|
||||||
|
|
||||||
const model = connectionMongo.model<T>(name, schema);
|
const model = connectionMongo.model<T>(name, schema);
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ import { mergeChatResponseData } from '@fastgpt/global/core/chat/utils';
|
|||||||
import { pushChatLog } from './pushChatLog';
|
import { pushChatLog } from './pushChatLog';
|
||||||
import { FlowNodeTypeEnum } from '@fastgpt/global/core/workflow/node/constant';
|
import { FlowNodeTypeEnum } from '@fastgpt/global/core/workflow/node/constant';
|
||||||
import { DispatchNodeResponseKeyEnum } from '@fastgpt/global/core/workflow/runtime/constants';
|
import { DispatchNodeResponseKeyEnum } from '@fastgpt/global/core/workflow/runtime/constants';
|
||||||
|
import { extractDeepestInteractive } from '@fastgpt/global/core/workflow/runtime/utils';
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
chatId: string;
|
chatId: string;
|
||||||
@@ -209,34 +210,24 @@ export const updateInteractiveChat = async ({
|
|||||||
}
|
}
|
||||||
})();
|
})();
|
||||||
|
|
||||||
if (interactiveValue.interactive.type === 'userSelect') {
|
let finalInteractive = extractDeepestInteractive(interactiveValue.interactive);
|
||||||
interactiveValue.interactive = {
|
|
||||||
...interactiveValue.interactive,
|
if (finalInteractive.type === 'userSelect') {
|
||||||
params: {
|
finalInteractive.params.userSelectedVal = userInteractiveVal;
|
||||||
...interactiveValue.interactive.params,
|
|
||||||
userSelectedVal: userInteractiveVal
|
|
||||||
}
|
|
||||||
};
|
|
||||||
} else if (
|
} else if (
|
||||||
interactiveValue.interactive.type === 'userInput' &&
|
finalInteractive.type === 'userInput' &&
|
||||||
typeof parsedUserInteractiveVal === 'object'
|
typeof parsedUserInteractiveVal === 'object'
|
||||||
) {
|
) {
|
||||||
interactiveValue.interactive = {
|
finalInteractive.params.inputForm = finalInteractive.params.inputForm.map((item) => {
|
||||||
...interactiveValue.interactive,
|
const itemValue = parsedUserInteractiveVal[item.label];
|
||||||
params: {
|
return itemValue !== undefined
|
||||||
...interactiveValue.interactive.params,
|
? {
|
||||||
inputForm: interactiveValue.interactive.params.inputForm.map((item) => {
|
...item,
|
||||||
const itemValue = parsedUserInteractiveVal[item.label];
|
value: itemValue
|
||||||
return itemValue !== undefined
|
}
|
||||||
? {
|
: item;
|
||||||
...item,
|
});
|
||||||
value: itemValue
|
finalInteractive.params.submitted = true;
|
||||||
}
|
|
||||||
: item;
|
|
||||||
}),
|
|
||||||
submitted: true
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (aiResponse.customFeedbacks) {
|
if (aiResponse.customFeedbacks) {
|
||||||
|
|||||||
@@ -73,6 +73,7 @@ import { dispatchLoopStart } from './loop/runLoopStart';
|
|||||||
import { dispatchFormInput } from './interactive/formInput';
|
import { dispatchFormInput } from './interactive/formInput';
|
||||||
import { dispatchToolParams } from './agent/runTool/toolParams';
|
import { dispatchToolParams } from './agent/runTool/toolParams';
|
||||||
import { getErrText } from '@fastgpt/global/common/error/utils';
|
import { getErrText } from '@fastgpt/global/common/error/utils';
|
||||||
|
import { filterModuleTypeList } from '@fastgpt/global/core/chat/utils';
|
||||||
|
|
||||||
const callbackMap: Record<FlowNodeTypeEnum, Function> = {
|
const callbackMap: Record<FlowNodeTypeEnum, Function> = {
|
||||||
[FlowNodeTypeEnum.workflowStart]: dispatchWorkflowStart,
|
[FlowNodeTypeEnum.workflowStart]: dispatchWorkflowStart,
|
||||||
@@ -140,6 +141,7 @@ export async function dispatchWorkFlow(data: Props): Promise<DispatchFlowRespons
|
|||||||
} else {
|
} else {
|
||||||
props.workflowDispatchDeep += 1;
|
props.workflowDispatchDeep += 1;
|
||||||
}
|
}
|
||||||
|
const isRootRuntime = props.workflowDispatchDeep === 1;
|
||||||
|
|
||||||
if (props.workflowDispatchDeep > 20) {
|
if (props.workflowDispatchDeep > 20) {
|
||||||
return {
|
return {
|
||||||
@@ -160,25 +162,28 @@ export async function dispatchWorkFlow(data: Props): Promise<DispatchFlowRespons
|
|||||||
let workflowRunTimes = 0;
|
let workflowRunTimes = 0;
|
||||||
|
|
||||||
// set sse response headers
|
// set sse response headers
|
||||||
if (stream && res) {
|
if (isRootRuntime) {
|
||||||
res.setHeader('Content-Type', 'text/event-stream;charset=utf-8');
|
res?.setHeader('Connection', 'keep-alive'); // Set keepalive for long connection
|
||||||
res.setHeader('Access-Control-Allow-Origin', '*');
|
if (stream && res) {
|
||||||
res.setHeader('X-Accel-Buffering', 'no');
|
res.setHeader('Content-Type', 'text/event-stream;charset=utf-8');
|
||||||
res.setHeader('Cache-Control', 'no-cache, no-transform');
|
res.setHeader('Access-Control-Allow-Origin', '*');
|
||||||
|
res.setHeader('X-Accel-Buffering', 'no');
|
||||||
|
res.setHeader('Cache-Control', 'no-cache, no-transform');
|
||||||
|
|
||||||
// 10s sends a message to prevent the browser from thinking that the connection is disconnected
|
// 10s sends a message to prevent the browser from thinking that the connection is disconnected
|
||||||
const sendStreamTimerSign = () => {
|
const sendStreamTimerSign = () => {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
props?.workflowStreamResponse?.({
|
props?.workflowStreamResponse?.({
|
||||||
event: SseResponseEventEnum.answer,
|
event: SseResponseEventEnum.answer,
|
||||||
data: textAdaptGptResponse({
|
data: textAdaptGptResponse({
|
||||||
text: ''
|
text: ''
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
sendStreamTimerSign();
|
sendStreamTimerSign();
|
||||||
}, 10000);
|
}, 10000);
|
||||||
};
|
};
|
||||||
sendStreamTimerSign();
|
sendStreamTimerSign();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
variables = {
|
variables = {
|
||||||
@@ -324,10 +329,9 @@ export async function dispatchWorkFlow(data: Props): Promise<DispatchFlowRespons
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (props.mode === 'debug') {
|
if (props.mode === 'debug') {
|
||||||
debugNextStepRunNodes = debugNextStepRunNodes.concat([
|
debugNextStepRunNodes = debugNextStepRunNodes.concat(
|
||||||
...nextStepActiveNodes,
|
props.lastInteractive ? nextStepActiveNodes : [...nextStepActiveNodes, ...nextStepSkipNodes]
|
||||||
...nextStepSkipNodes
|
);
|
||||||
]);
|
|
||||||
return {
|
return {
|
||||||
nextStepActiveNodes: [],
|
nextStepActiveNodes: [],
|
||||||
nextStepSkipNodes: []
|
nextStepSkipNodes: []
|
||||||
@@ -373,7 +377,7 @@ export async function dispatchWorkFlow(data: Props): Promise<DispatchFlowRespons
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Tool call, not need interactive response
|
// Tool call, not need interactive response
|
||||||
if (!props.isToolCall) {
|
if (!props.isToolCall && isRootRuntime) {
|
||||||
props.workflowStreamResponse?.({
|
props.workflowStreamResponse?.({
|
||||||
event: SseResponseEventEnum.interactive,
|
event: SseResponseEventEnum.interactive,
|
||||||
data: { interactive: interactiveResult }
|
data: { interactive: interactiveResult }
|
||||||
@@ -427,14 +431,6 @@ export async function dispatchWorkFlow(data: Props): Promise<DispatchFlowRespons
|
|||||||
})();
|
})();
|
||||||
|
|
||||||
if (!nodeRunResult) return [];
|
if (!nodeRunResult) return [];
|
||||||
if (res?.closed) {
|
|
||||||
addLog.warn('Request is closed', {
|
|
||||||
appId: props.runningAppInfo.id,
|
|
||||||
nodeId: node.nodeId,
|
|
||||||
nodeName: node.name
|
|
||||||
});
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
特殊情况:
|
特殊情况:
|
||||||
@@ -491,6 +487,15 @@ export async function dispatchWorkFlow(data: Props): Promise<DispatchFlowRespons
|
|||||||
await Promise.all(nextStepSkipNodes.map((node) => checkNodeCanRun(node, skippedNodeIdList)))
|
await Promise.all(nextStepSkipNodes.map((node) => checkNodeCanRun(node, skippedNodeIdList)))
|
||||||
).flat();
|
).flat();
|
||||||
|
|
||||||
|
if (res?.closed) {
|
||||||
|
addLog.warn('Request is closed', {
|
||||||
|
appId: props.runningAppInfo.id,
|
||||||
|
nodeId: node.nodeId,
|
||||||
|
nodeName: node.name
|
||||||
|
});
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
return [
|
return [
|
||||||
...nextStepActiveNodes,
|
...nextStepActiveNodes,
|
||||||
...nextStepSkipNodes,
|
...nextStepSkipNodes,
|
||||||
@@ -631,8 +636,9 @@ export async function dispatchWorkFlow(data: Props): Promise<DispatchFlowRespons
|
|||||||
if (
|
if (
|
||||||
version === 'v2' &&
|
version === 'v2' &&
|
||||||
!props.isToolCall &&
|
!props.isToolCall &&
|
||||||
!props.runningAppInfo.isChildApp &&
|
isRootRuntime &&
|
||||||
formatResponseData
|
formatResponseData &&
|
||||||
|
!(!props.responseDetail && filterModuleTypeList.includes(formatResponseData.moduleType))
|
||||||
) {
|
) {
|
||||||
props.workflowStreamResponse?.({
|
props.workflowStreamResponse?.({
|
||||||
event: SseResponseEventEnum.flowNodeResponse,
|
event: SseResponseEventEnum.flowNodeResponse,
|
||||||
@@ -719,7 +725,9 @@ export async function dispatchWorkFlow(data: Props): Promise<DispatchFlowRespons
|
|||||||
entryNodeIds: nodeInteractiveResponse.entryNodeIds,
|
entryNodeIds: nodeInteractiveResponse.entryNodeIds,
|
||||||
interactiveResponse: nodeInteractiveResponse.interactiveResponse
|
interactiveResponse: nodeInteractiveResponse.interactiveResponse
|
||||||
});
|
});
|
||||||
chatAssistantResponse.push(interactiveAssistant);
|
if (isRootRuntime) {
|
||||||
|
chatAssistantResponse.push(interactiveAssistant);
|
||||||
|
}
|
||||||
return interactiveAssistant.interactive;
|
return interactiveAssistant.interactive;
|
||||||
}
|
}
|
||||||
})();
|
})();
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ import type {
|
|||||||
UserInputInteractive
|
UserInputInteractive
|
||||||
} from '@fastgpt/global/core/workflow/template/system/interactive/type';
|
} from '@fastgpt/global/core/workflow/template/system/interactive/type';
|
||||||
import { addLog } from '../../../../common/system/log';
|
import { addLog } from '../../../../common/system/log';
|
||||||
import { getLastInteractiveValue } from '@fastgpt/global/core/workflow/runtime/utils';
|
|
||||||
|
|
||||||
type Props = ModuleDispatchProps<{
|
type Props = ModuleDispatchProps<{
|
||||||
[NodeInputKeyEnum.description]: string;
|
[NodeInputKeyEnum.description]: string;
|
||||||
@@ -29,13 +28,13 @@ export const dispatchFormInput = async (props: Props): Promise<FormInputResponse
|
|||||||
histories,
|
histories,
|
||||||
node,
|
node,
|
||||||
params: { description, userInputForms },
|
params: { description, userInputForms },
|
||||||
query
|
query,
|
||||||
|
lastInteractive
|
||||||
} = props;
|
} = props;
|
||||||
const { isEntry } = node;
|
const { isEntry } = node;
|
||||||
const interactive = getLastInteractiveValue(histories);
|
|
||||||
|
|
||||||
// Interactive node is not the entry node, return interactive result
|
// Interactive node is not the entry node, return interactive result
|
||||||
if (!isEntry || interactive?.type !== 'userInput') {
|
if (!isEntry || lastInteractive?.type !== 'userInput') {
|
||||||
return {
|
return {
|
||||||
[DispatchNodeResponseKeyEnum.interactive]: {
|
[DispatchNodeResponseKeyEnum.interactive]: {
|
||||||
type: 'userInput',
|
type: 'userInput',
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ import type {
|
|||||||
UserSelectOptionItemType
|
UserSelectOptionItemType
|
||||||
} from '@fastgpt/global/core/workflow/template/system/interactive/type';
|
} from '@fastgpt/global/core/workflow/template/system/interactive/type';
|
||||||
import { chatValue2RuntimePrompt } from '@fastgpt/global/core/chat/adapt';
|
import { chatValue2RuntimePrompt } from '@fastgpt/global/core/chat/adapt';
|
||||||
import { getLastInteractiveValue } from '@fastgpt/global/core/workflow/runtime/utils';
|
|
||||||
|
|
||||||
type Props = ModuleDispatchProps<{
|
type Props = ModuleDispatchProps<{
|
||||||
[NodeInputKeyEnum.description]: string;
|
[NodeInputKeyEnum.description]: string;
|
||||||
@@ -27,13 +26,13 @@ export const dispatchUserSelect = async (props: Props): Promise<UserSelectRespon
|
|||||||
histories,
|
histories,
|
||||||
node,
|
node,
|
||||||
params: { description, userSelectOptions },
|
params: { description, userSelectOptions },
|
||||||
query
|
query,
|
||||||
|
lastInteractive
|
||||||
} = props;
|
} = props;
|
||||||
const { nodeId, isEntry } = node;
|
const { nodeId, isEntry } = node;
|
||||||
const interactive = getLastInteractiveValue(histories);
|
|
||||||
|
|
||||||
// Interactive node is not the entry node, return interactive result
|
// Interactive node is not the entry node, return interactive result
|
||||||
if (!isEntry || interactive?.type !== 'userSelect') {
|
if (!isEntry || lastInteractive?.type !== 'userSelect') {
|
||||||
return {
|
return {
|
||||||
[DispatchNodeResponseKeyEnum.interactive]: {
|
[DispatchNodeResponseKeyEnum.interactive]: {
|
||||||
type: 'userSelect',
|
type: 'userSelect',
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ import { authAppByTmbId } from '../../../../support/permission/app/auth';
|
|||||||
import { ReadPermissionVal } from '@fastgpt/global/support/permission/constant';
|
import { ReadPermissionVal } from '@fastgpt/global/support/permission/constant';
|
||||||
import { getAppVersionById } from '../../../app/version/controller';
|
import { getAppVersionById } from '../../../app/version/controller';
|
||||||
import { parseUrlToFileType } from '@fastgpt/global/common/file/tools';
|
import { parseUrlToFileType } from '@fastgpt/global/common/file/tools';
|
||||||
|
import { ChildrenInteractive } from '@fastgpt/global/core/workflow/template/system/interactive/type';
|
||||||
|
|
||||||
type Props = ModuleDispatchProps<{
|
type Props = ModuleDispatchProps<{
|
||||||
[NodeInputKeyEnum.userChatInput]: string;
|
[NodeInputKeyEnum.userChatInput]: string;
|
||||||
@@ -27,6 +28,7 @@ type Props = ModuleDispatchProps<{
|
|||||||
[NodeInputKeyEnum.fileUrlList]?: string[];
|
[NodeInputKeyEnum.fileUrlList]?: string[];
|
||||||
}>;
|
}>;
|
||||||
type Response = DispatchNodeResultType<{
|
type Response = DispatchNodeResultType<{
|
||||||
|
[DispatchNodeResponseKeyEnum.interactive]?: ChildrenInteractive;
|
||||||
[NodeOutputKeyEnum.answerText]: string;
|
[NodeOutputKeyEnum.answerText]: string;
|
||||||
[NodeOutputKeyEnum.history]: ChatItemType[];
|
[NodeOutputKeyEnum.history]: ChatItemType[];
|
||||||
}>;
|
}>;
|
||||||
@@ -36,6 +38,7 @@ export const dispatchRunAppNode = async (props: Props): Promise<Response> => {
|
|||||||
runningAppInfo,
|
runningAppInfo,
|
||||||
histories,
|
histories,
|
||||||
query,
|
query,
|
||||||
|
lastInteractive,
|
||||||
node: { pluginId: appId, version },
|
node: { pluginId: appId, version },
|
||||||
workflowStreamResponse,
|
workflowStreamResponse,
|
||||||
params,
|
params,
|
||||||
@@ -100,31 +103,41 @@ export const dispatchRunAppNode = async (props: Props): Promise<Response> => {
|
|||||||
appId: String(appData._id)
|
appId: String(appData._id)
|
||||||
};
|
};
|
||||||
|
|
||||||
const { flowResponses, flowUsages, assistantResponses, runTimes } = await dispatchWorkFlow({
|
const childrenInteractive =
|
||||||
...props,
|
lastInteractive?.type === 'childrenInteractive'
|
||||||
// Rewrite stream mode
|
? lastInteractive.params.childrenResponse
|
||||||
...(system_forbid_stream
|
: undefined;
|
||||||
? {
|
const entryNodeIds = getWorkflowEntryNodeIds(nodes, childrenInteractive || undefined);
|
||||||
stream: false,
|
const runtimeNodes = storeNodes2RuntimeNodes(nodes, entryNodeIds);
|
||||||
workflowStreamResponse: undefined
|
const runtimeEdges = initWorkflowEdgeStatus(edges, childrenInteractive);
|
||||||
}
|
const theQuery = childrenInteractive
|
||||||
: {}),
|
? query
|
||||||
runningAppInfo: {
|
: runtimePrompt2ChatsValue({ files: userInputFiles, text: userChatInput });
|
||||||
id: String(appData._id),
|
|
||||||
teamId: String(appData.teamId),
|
const { flowResponses, flowUsages, assistantResponses, runTimes, workflowInteractiveResponse } =
|
||||||
tmbId: String(appData.tmbId),
|
await dispatchWorkFlow({
|
||||||
isChildApp: true
|
...props,
|
||||||
},
|
lastInteractive: childrenInteractive,
|
||||||
runtimeNodes: storeNodes2RuntimeNodes(nodes, getWorkflowEntryNodeIds(nodes)),
|
// Rewrite stream mode
|
||||||
runtimeEdges: initWorkflowEdgeStatus(edges),
|
...(system_forbid_stream
|
||||||
histories: chatHistories,
|
? {
|
||||||
variables: childrenRunVariables,
|
stream: false,
|
||||||
query: runtimePrompt2ChatsValue({
|
workflowStreamResponse: undefined
|
||||||
files: userInputFiles,
|
}
|
||||||
text: userChatInput
|
: {}),
|
||||||
}),
|
runningAppInfo: {
|
||||||
chatConfig
|
id: String(appData._id),
|
||||||
});
|
teamId: String(appData.teamId),
|
||||||
|
tmbId: String(appData.tmbId),
|
||||||
|
isChildApp: true
|
||||||
|
},
|
||||||
|
runtimeNodes,
|
||||||
|
runtimeEdges,
|
||||||
|
histories: chatHistories,
|
||||||
|
variables: childrenRunVariables,
|
||||||
|
query: theQuery,
|
||||||
|
chatConfig
|
||||||
|
});
|
||||||
|
|
||||||
const completeMessages = chatHistories.concat([
|
const completeMessages = chatHistories.concat([
|
||||||
{
|
{
|
||||||
@@ -142,6 +155,14 @@ export const dispatchRunAppNode = async (props: Props): Promise<Response> => {
|
|||||||
const usagePoints = flowUsages.reduce((sum, item) => sum + (item.totalPoints || 0), 0);
|
const usagePoints = flowUsages.reduce((sum, item) => sum + (item.totalPoints || 0), 0);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
[DispatchNodeResponseKeyEnum.interactive]: workflowInteractiveResponse
|
||||||
|
? {
|
||||||
|
type: 'childrenInteractive',
|
||||||
|
params: {
|
||||||
|
childrenResponse: workflowInteractiveResponse
|
||||||
|
}
|
||||||
|
}
|
||||||
|
: undefined,
|
||||||
assistantResponses: system_forbid_stream ? [] : assistantResponses,
|
assistantResponses: system_forbid_stream ? [] : assistantResponses,
|
||||||
[DispatchNodeResponseKeyEnum.runTimes]: runTimes,
|
[DispatchNodeResponseKeyEnum.runTimes]: runTimes,
|
||||||
[DispatchNodeResponseKeyEnum.nodeResponse]: {
|
[DispatchNodeResponseKeyEnum.nodeResponse]: {
|
||||||
|
|||||||
26
packages/service/support/operationLog/addOperationLog.ts
Normal file
26
packages/service/support/operationLog/addOperationLog.ts
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
import { MongoOperationLog } from './schema';
|
||||||
|
import { OperationLogEventEnum } from '@fastgpt/global/support/operationLog/constants';
|
||||||
|
import { TemplateParamsMap } from './constants';
|
||||||
|
import { retryFn } from '../../../global/common/system/utils';
|
||||||
|
|
||||||
|
export function addOperationLog<T extends OperationLogEventEnum>({
|
||||||
|
teamId,
|
||||||
|
tmbId,
|
||||||
|
event,
|
||||||
|
params
|
||||||
|
}: {
|
||||||
|
tmbId: string;
|
||||||
|
teamId: string;
|
||||||
|
event: T;
|
||||||
|
params?: TemplateParamsMap[T];
|
||||||
|
}) {
|
||||||
|
console.log('Insert log');
|
||||||
|
retryFn(() =>
|
||||||
|
MongoOperationLog.create({
|
||||||
|
tmbId: tmbId,
|
||||||
|
teamId: teamId,
|
||||||
|
event,
|
||||||
|
metadata: params
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
85
packages/service/support/operationLog/constants.ts
Normal file
85
packages/service/support/operationLog/constants.ts
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
import { OperationLogEventEnum } from '@fastgpt/global/support/operationLog/constants';
|
||||||
|
import { i18nT } from '../../../web/i18n/utils';
|
||||||
|
|
||||||
|
export const operationLogI18nMap = {
|
||||||
|
[OperationLogEventEnum.LOGIN]: {
|
||||||
|
content: i18nT('account_team:log_login'),
|
||||||
|
typeLabel: i18nT('account_team:login')
|
||||||
|
},
|
||||||
|
[OperationLogEventEnum.CREATE_INVITATION_LINK]: {
|
||||||
|
content: i18nT('account_team:log_create_invitation_link'),
|
||||||
|
typeLabel: i18nT('account_team:create_invitation_link')
|
||||||
|
},
|
||||||
|
[OperationLogEventEnum.JOIN_TEAM]: {
|
||||||
|
content: i18nT('account_team:log_join_team'),
|
||||||
|
typeLabel: i18nT('account_team:join_team')
|
||||||
|
},
|
||||||
|
[OperationLogEventEnum.CHANGE_MEMBER_NAME]: {
|
||||||
|
content: i18nT('account_team:log_change_member_name'),
|
||||||
|
typeLabel: i18nT('account_team:change_member_name')
|
||||||
|
},
|
||||||
|
[OperationLogEventEnum.KICK_OUT_TEAM]: {
|
||||||
|
content: i18nT('account_team:log_kick_out_team'),
|
||||||
|
typeLabel: i18nT('account_team:kick_out_team')
|
||||||
|
},
|
||||||
|
[OperationLogEventEnum.CREATE_DEPARTMENT]: {
|
||||||
|
content: i18nT('account_team:log_create_department'),
|
||||||
|
typeLabel: i18nT('account_team:create_department')
|
||||||
|
},
|
||||||
|
[OperationLogEventEnum.CHANGE_DEPARTMENT]: {
|
||||||
|
content: i18nT('account_team:log_change_department'),
|
||||||
|
typeLabel: i18nT('account_team:change_department_name')
|
||||||
|
},
|
||||||
|
[OperationLogEventEnum.DELETE_DEPARTMENT]: {
|
||||||
|
content: i18nT('account_team:log_delete_department'),
|
||||||
|
typeLabel: i18nT('account_team:delete_department')
|
||||||
|
},
|
||||||
|
[OperationLogEventEnum.RELOCATE_DEPARTMENT]: {
|
||||||
|
content: i18nT('account_team:log_relocate_department'),
|
||||||
|
typeLabel: i18nT('account_team:relocate_department')
|
||||||
|
},
|
||||||
|
[OperationLogEventEnum.CREATE_GROUP]: {
|
||||||
|
content: i18nT('account_team:log_create_group'),
|
||||||
|
typeLabel: i18nT('account_team:create_group')
|
||||||
|
},
|
||||||
|
[OperationLogEventEnum.DELETE_GROUP]: {
|
||||||
|
content: i18nT('account_team:log_delete_group'),
|
||||||
|
typeLabel: i18nT('account_team:delete_group')
|
||||||
|
},
|
||||||
|
[OperationLogEventEnum.ASSIGN_PERMISSION]: {
|
||||||
|
content: i18nT('account_team:log_assign_permission'),
|
||||||
|
typeLabel: i18nT('account_team:assign_permission')
|
||||||
|
}
|
||||||
|
} as const;
|
||||||
|
|
||||||
|
export type TemplateParamsMap = {
|
||||||
|
[OperationLogEventEnum.LOGIN]: { name?: string };
|
||||||
|
[OperationLogEventEnum.CREATE_INVITATION_LINK]: { name?: string; link: string };
|
||||||
|
[OperationLogEventEnum.JOIN_TEAM]: { name?: string; link: string };
|
||||||
|
[OperationLogEventEnum.CHANGE_MEMBER_NAME]: {
|
||||||
|
name?: string;
|
||||||
|
memberName: string;
|
||||||
|
newName: string;
|
||||||
|
};
|
||||||
|
[OperationLogEventEnum.KICK_OUT_TEAM]: {
|
||||||
|
name?: string;
|
||||||
|
memberName: string;
|
||||||
|
};
|
||||||
|
[OperationLogEventEnum.CREATE_DEPARTMENT]: { name?: string; departmentName: string };
|
||||||
|
[OperationLogEventEnum.CHANGE_DEPARTMENT]: {
|
||||||
|
name?: string;
|
||||||
|
departmentName: string;
|
||||||
|
};
|
||||||
|
[OperationLogEventEnum.DELETE_DEPARTMENT]: { name?: string; departmentName: string };
|
||||||
|
[OperationLogEventEnum.RELOCATE_DEPARTMENT]: {
|
||||||
|
name?: string;
|
||||||
|
departmentName: string;
|
||||||
|
};
|
||||||
|
[OperationLogEventEnum.CREATE_GROUP]: { name?: string; groupName: string };
|
||||||
|
[OperationLogEventEnum.DELETE_GROUP]: { name?: string; groupName: string };
|
||||||
|
[OperationLogEventEnum.ASSIGN_PERMISSION]: {
|
||||||
|
name?: string;
|
||||||
|
objectName: string;
|
||||||
|
permission: string;
|
||||||
|
};
|
||||||
|
};
|
||||||
40
packages/service/support/operationLog/schema.ts
Normal file
40
packages/service/support/operationLog/schema.ts
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
import { Schema, getMongoLogModel } from '../../common/mongo';
|
||||||
|
import type { OperationLogSchema } from '@fastgpt/global/support/operationLog/type';
|
||||||
|
import { OperationLogEventEnum } from '@fastgpt/global/support/operationLog/constants';
|
||||||
|
import {
|
||||||
|
TeamCollectionName,
|
||||||
|
TeamMemberCollectionName
|
||||||
|
} from '@fastgpt/global/support/user/team/constant';
|
||||||
|
|
||||||
|
export const OperationLogCollectionName = 'operationLog';
|
||||||
|
|
||||||
|
const OperationLogSchema = new Schema({
|
||||||
|
tmbId: {
|
||||||
|
type: Schema.Types.ObjectId,
|
||||||
|
ref: TeamMemberCollectionName,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
teamId: {
|
||||||
|
type: Schema.Types.ObjectId,
|
||||||
|
ref: TeamCollectionName,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
timestamp: {
|
||||||
|
type: Date,
|
||||||
|
default: () => new Date()
|
||||||
|
},
|
||||||
|
event: {
|
||||||
|
type: String,
|
||||||
|
enum: Object.values(OperationLogEventEnum),
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
metadata: {
|
||||||
|
type: Object,
|
||||||
|
default: {}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
export const MongoOperationLog = getMongoLogModel<OperationLogSchema>(
|
||||||
|
OperationLogCollectionName,
|
||||||
|
OperationLogSchema
|
||||||
|
);
|
||||||
@@ -2,7 +2,7 @@ import { TeamPermission } from '@fastgpt/global/support/permission/user/controll
|
|||||||
import { AuthModeType, AuthResponseType } from '../type';
|
import { AuthModeType, AuthResponseType } from '../type';
|
||||||
import { TeamErrEnum } from '@fastgpt/global/common/error/code/team';
|
import { TeamErrEnum } from '@fastgpt/global/common/error/code/team';
|
||||||
import { authUserPer } from '../user/auth';
|
import { authUserPer } from '../user/auth';
|
||||||
import { ManagePermissionVal } from '@fastgpt/global/support/permission/constant';
|
import { TeamManagePermissionVal } from '@fastgpt/global/support/permission/user/constant';
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Team manager can control org
|
Team manager can control org
|
||||||
@@ -15,7 +15,7 @@ export const authOrgMember = async ({
|
|||||||
} & AuthModeType): Promise<AuthResponseType> => {
|
} & AuthModeType): Promise<AuthResponseType> => {
|
||||||
const result = await authUserPer({
|
const result = await authUserPer({
|
||||||
...props,
|
...props,
|
||||||
per: ManagePermissionVal
|
per: TeamManagePermissionVal
|
||||||
});
|
});
|
||||||
const { teamId, tmbId, isRoot, tmb } = result;
|
const { teamId, tmbId, isRoot, tmb } = result;
|
||||||
|
|
||||||
|
|||||||
@@ -104,8 +104,11 @@ export async function addSourceMember<T extends { tmbId: string }>({
|
|||||||
const tmb = tmbList.find((tmb) => String(tmb._id) === String(item.tmbId));
|
const tmb = tmbList.find((tmb) => String(tmb._id) === String(item.tmbId));
|
||||||
if (!tmb) return;
|
if (!tmb) return;
|
||||||
|
|
||||||
|
// @ts-ignore
|
||||||
|
const formatItem = typeof item.toObject === 'function' ? item.toObject() : item;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
...item,
|
...formatItem,
|
||||||
sourceMember: { name: tmb.name, avatar: tmb.avatar, status: tmb.status }
|
sourceMember: { name: tmb.name, avatar: tmb.avatar, status: tmb.status }
|
||||||
};
|
};
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -5,17 +5,23 @@
|
|||||||
"7days": "7 Days",
|
"7days": "7 Days",
|
||||||
"accept": "accept",
|
"accept": "accept",
|
||||||
"action": "operate",
|
"action": "operate",
|
||||||
|
"assign_permission": "Permission change",
|
||||||
|
"change_department_name": "Department Editor",
|
||||||
|
"change_member_name": "Member name change",
|
||||||
"confirm_delete_group": "Confirm to delete group?",
|
"confirm_delete_group": "Confirm to delete group?",
|
||||||
"confirm_delete_member": "Confirm to delete member?",
|
"confirm_delete_member": "Confirm to delete member?",
|
||||||
"confirm_delete_org": "Confirm to delete organization?",
|
"confirm_delete_org": "Confirm to delete organization?",
|
||||||
"confirm_forbidden": "Confirm forbidden",
|
"confirm_forbidden": "Confirm forbidden",
|
||||||
"confirm_leave_team": "Confirmed to leave the team? \nAfter exiting, all your resources in the team are transferred to the team owner.",
|
"confirm_leave_team": "Confirmed to leave the team? \nAfter exiting, all your resources in the team are transferred to the team owner.",
|
||||||
"copy_link": "Copy link",
|
"copy_link": "Copy link",
|
||||||
|
"create_department": "Create a sub-department",
|
||||||
"create_group": "Create group",
|
"create_group": "Create group",
|
||||||
"create_invitation_link": "Create Invitation Link",
|
"create_invitation_link": "Create Invitation Link",
|
||||||
"create_org": "Create organization",
|
"create_org": "Create organization",
|
||||||
"create_sub_org": "Create sub-organization",
|
"create_sub_org": "Create sub-organization",
|
||||||
"delete": "delete",
|
"delete": "delete",
|
||||||
|
"delete_department": "Delete sub-department",
|
||||||
|
"delete_group": "Delete a group",
|
||||||
"delete_org": "Delete organization",
|
"delete_org": "Delete organization",
|
||||||
"edit_info": "Edit information",
|
"edit_info": "Edit information",
|
||||||
"edit_member": "Edit user",
|
"edit_member": "Edit user",
|
||||||
@@ -37,21 +43,51 @@
|
|||||||
"invitation_link_list": "Invitation link list",
|
"invitation_link_list": "Invitation link list",
|
||||||
"invite_member": "Invite members",
|
"invite_member": "Invite members",
|
||||||
"invited": "Invited",
|
"invited": "Invited",
|
||||||
|
"join_team": "Join the team",
|
||||||
|
"kick_out_team": "Remove members",
|
||||||
"label_sync": "Tag sync",
|
"label_sync": "Tag sync",
|
||||||
"leave_team_failed": "Leaving the team exception",
|
"leave_team_failed": "Leaving the team exception",
|
||||||
|
"log_assign_permission": "[{{name}}] Updated the permissions of [{{objectName}}]: [Application creation: [{{appCreate}}], Knowledge Base: [{{datasetCreate}}], API Key: [{{apiKeyCreate}}], Management: [{{manage}}]]",
|
||||||
|
"log_change_department": "【{{name}}】Updated department【{{departmentName}}】",
|
||||||
|
"log_change_member_name": "【{{name}}】Rename member [{{memberName}}] to 【{{newName}}】",
|
||||||
|
"log_create_department": "【{{name}}】Department【{{departmentName}}】",
|
||||||
|
"log_create_group": "【{{name}}】Created group [{{groupName}}]",
|
||||||
|
"log_create_invitation_link": "【{{name}}】Created invitation link【{{link}}】",
|
||||||
|
"log_delete_department": "{{name}} deleted department {{departmentName}}",
|
||||||
|
"log_delete_group": "{{name}} deleted group {{groupName}}",
|
||||||
|
"log_details": "Details",
|
||||||
|
"log_join_team": "【{{name}}】Join the team through the invitation link 【{{link}}】",
|
||||||
|
"log_kick_out_team": "{{name}} removed member {{memberName}}",
|
||||||
|
"log_login": "【{{name}}】Logined in the system",
|
||||||
|
"log_relocate_department": "【{{name}}】Displayed department【{{departmentName}}】",
|
||||||
|
"log_time": "Operation time",
|
||||||
|
"log_type": "Operation Type",
|
||||||
|
"log_user": "Operator",
|
||||||
|
"login": "Log in",
|
||||||
"manage_member": "Managing members",
|
"manage_member": "Managing members",
|
||||||
"member": "member",
|
"member": "member",
|
||||||
"member_group": "Belonging to member group",
|
"member_group": "Belonging to member group",
|
||||||
"move_member": "Move member",
|
"move_member": "Move member",
|
||||||
"move_org": "Move organization",
|
"move_org": "Move organization",
|
||||||
|
"operation_log": "log",
|
||||||
"org": "organization",
|
"org": "organization",
|
||||||
"org_description": "Organization description",
|
"org_description": "Organization description",
|
||||||
"org_name": "Organization name",
|
"org_name": "Organization name",
|
||||||
"owner": "owner",
|
"owner": "owner",
|
||||||
"permission": "Permissions",
|
"permission": "Permissions",
|
||||||
|
"permission_apikeyCreate": "Create API Key",
|
||||||
|
"permission_apikeyCreate_Tip": "Can create global APIKeys",
|
||||||
|
"permission_appCreate": "Create Application",
|
||||||
|
"permission_appCreate_tip": "Can create applications in the root directory (creation permissions in folders are controlled by the folder)",
|
||||||
|
"permission_datasetCreate": "Create Knowledge Base",
|
||||||
|
"permission_datasetCreate_Tip": "Can create knowledge bases in the root directory (creation permissions in folders are controlled by the folder)",
|
||||||
|
"permission_manage": "Admin",
|
||||||
|
"permission_manage_tip": "Can manage members, create groups, manage all groups, and assign permissions to groups and members",
|
||||||
|
"relocate_department": "Department Mobile",
|
||||||
"remark": "remark",
|
"remark": "remark",
|
||||||
"remove_tip": "Confirm to remove {{username}} from the team?",
|
"remove_tip": "Confirm to remove {{username}} from the team?",
|
||||||
"retain_admin_permissions": "Keep administrator rights",
|
"retain_admin_permissions": "Keep administrator rights",
|
||||||
|
"search_log": "Search log",
|
||||||
"search_member_group_name": "Search member/group name",
|
"search_member_group_name": "Search member/group name",
|
||||||
"total_team_members": "{{amount}} members in total",
|
"total_team_members": "{{amount}} members in total",
|
||||||
"transfer_ownership": "transfer owner",
|
"transfer_ownership": "transfer owner",
|
||||||
|
|||||||
@@ -100,7 +100,6 @@
|
|||||||
"team.group.manage_tip": "Can manage members, create groups, manage all groups, assign permissions to groups and members",
|
"team.group.manage_tip": "Can manage members, create groups, manage all groups, assign permissions to groups and members",
|
||||||
"team.group.members": "member",
|
"team.group.members": "member",
|
||||||
"team.group.name": "Group name",
|
"team.group.name": "Group name",
|
||||||
"team.group.permission.manage": "administrator",
|
|
||||||
"team.group.permission.write": "Workbench/knowledge base creation",
|
"team.group.permission.write": "Workbench/knowledge base creation",
|
||||||
"team.group.permission_tip": "Members with individually configured permissions will follow the individual permission configuration and will no longer be affected by group permissions.\n\nIf a member is in multiple permission groups, the member's permissions are combined.",
|
"team.group.permission_tip": "Members with individually configured permissions will follow the individual permission configuration and will no longer be affected by group permissions.\n\nIf a member is in multiple permission groups, the member's permissions are combined.",
|
||||||
"team.group.role.admin": "administrator",
|
"team.group.role.admin": "administrator",
|
||||||
@@ -112,5 +111,6 @@
|
|||||||
"team.manage_collaborators": "Manage Collaborators",
|
"team.manage_collaborators": "Manage Collaborators",
|
||||||
"team.no_collaborators": "No Collaborators",
|
"team.no_collaborators": "No Collaborators",
|
||||||
"team.org.org": "Organization",
|
"team.org.org": "Organization",
|
||||||
"team.write_role_member": ""
|
"team.write_role_member": "Write Permission",
|
||||||
|
"team.collaborator.added": "Added"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,9 @@
|
|||||||
"7days": "7天",
|
"7days": "7天",
|
||||||
"accept": "接受",
|
"accept": "接受",
|
||||||
"action": "操作",
|
"action": "操作",
|
||||||
|
"assign_permission": "权限变更",
|
||||||
|
"change_department_name": "部门编辑",
|
||||||
|
"change_member_name": "成员改名",
|
||||||
"confirm_delete_from_org": "确认将 {{username}} 移出部门?",
|
"confirm_delete_from_org": "确认将 {{username}} 移出部门?",
|
||||||
"confirm_delete_from_team": "确认将 {{username}} 移出团队?",
|
"confirm_delete_from_team": "确认将 {{username}} 移出团队?",
|
||||||
"confirm_delete_group": "确认删除群组?",
|
"confirm_delete_group": "确认删除群组?",
|
||||||
@@ -12,13 +15,16 @@
|
|||||||
"confirm_forbidden": "确认停用",
|
"confirm_forbidden": "确认停用",
|
||||||
"confirm_leave_team": "确认离开该团队? \n退出后,您在该团队所有的资源均转让给团队所有者。",
|
"confirm_leave_team": "确认离开该团队? \n退出后,您在该团队所有的资源均转让给团队所有者。",
|
||||||
"copy_link": "复制链接",
|
"copy_link": "复制链接",
|
||||||
|
"create_department": "创建子部门",
|
||||||
"create_group": "创建群组",
|
"create_group": "创建群组",
|
||||||
"create_invitation_link": "创建邀请链接",
|
"create_invitation_link": "创建邀请链接",
|
||||||
"create_org": "创建部门",
|
"create_org": "创建部门",
|
||||||
"create_sub_org": "创建子部门",
|
"create_sub_org": "创建子部门",
|
||||||
"delete": "删除",
|
"delete": "删除",
|
||||||
|
"delete_department": "删除子部门",
|
||||||
"delete_from_org": "移出部门",
|
"delete_from_org": "移出部门",
|
||||||
"delete_from_team": "移出团队",
|
"delete_from_team": "移出团队",
|
||||||
|
"delete_group": "删除群组",
|
||||||
"delete_org": "删除部门",
|
"delete_org": "删除部门",
|
||||||
"edit_info": "编辑信息",
|
"edit_info": "编辑信息",
|
||||||
"edit_member": "编辑用户",
|
"edit_member": "编辑用户",
|
||||||
@@ -41,27 +47,37 @@
|
|||||||
"invitation_link_list": "链接列表",
|
"invitation_link_list": "链接列表",
|
||||||
"invite_member": "邀请成员",
|
"invite_member": "邀请成员",
|
||||||
"invited": "已邀请",
|
"invited": "已邀请",
|
||||||
|
"join_team": "加入团队",
|
||||||
"join_update_time": "加入/更新时间",
|
"join_update_time": "加入/更新时间",
|
||||||
|
"kick_out_team": "移除成员",
|
||||||
"label_sync": "标签同步",
|
"label_sync": "标签同步",
|
||||||
"leave": "已离职",
|
"leave": "已离职",
|
||||||
"leave_team_failed": "离开团队异常",
|
"leave_team_failed": "离开团队异常",
|
||||||
|
"log_details": "详情",
|
||||||
|
"log_time": "操作时间",
|
||||||
|
"log_type": "操作类型",
|
||||||
|
"log_user": "操作人员",
|
||||||
|
"login": "登录",
|
||||||
"manage_member": "管理成员",
|
"manage_member": "管理成员",
|
||||||
"member": "成员",
|
"member": "成员",
|
||||||
"member_group": "所属群组",
|
"member_group": "所属群组",
|
||||||
"move_member": "移动成员",
|
"move_member": "移动成员",
|
||||||
"move_org": "移动部门",
|
"move_org": "移动部门",
|
||||||
"notification_recieve": "团队通知接收",
|
"notification_recieve": "团队通知接收",
|
||||||
|
"operation_log": "日志",
|
||||||
"org": "部门",
|
"org": "部门",
|
||||||
"org_description": "介绍",
|
"org_description": "介绍",
|
||||||
"org_name": "部门名称",
|
"org_name": "部门名称",
|
||||||
"owner": "所有者",
|
"owner": "所有者",
|
||||||
"permission": "权限",
|
"permission": "权限",
|
||||||
"please_bind_contact": "请绑定联系方式",
|
"please_bind_contact": "请绑定联系方式",
|
||||||
|
"relocate_department": "部门移动",
|
||||||
"remark": "备注",
|
"remark": "备注",
|
||||||
"remove_tip": "确认将 {{username}} 移出团队?成员将被标记为“已离职”,不删除操作数据,账号下资源自动转让给团队所有者。",
|
"remove_tip": "确认将 {{username}} 移出团队?成员将被标记为“已离职”,不删除操作数据,账号下资源自动转让给团队所有者。",
|
||||||
"restore_tip": "确认将 {{username}} 加入团队吗?仅恢复该成员账号可用性及相关权限,无法恢复账号下资源。",
|
"restore_tip": "确认将 {{username}} 加入团队吗?仅恢复该成员账号可用性及相关权限,无法恢复账号下资源。",
|
||||||
"restore_tip_title": "恢复确认",
|
"restore_tip_title": "恢复确认",
|
||||||
"retain_admin_permissions": "保留管理员权限",
|
"retain_admin_permissions": "保留管理员权限",
|
||||||
|
"search_log": "搜索日志",
|
||||||
"search_member": "搜索成员",
|
"search_member": "搜索成员",
|
||||||
"search_member_group_name": "搜索成员/群组名称",
|
"search_member_group_name": "搜索成员/群组名称",
|
||||||
"search_org": "搜索部门",
|
"search_org": "搜索部门",
|
||||||
@@ -77,5 +93,25 @@
|
|||||||
"user_team_invite_member": "邀请成员",
|
"user_team_invite_member": "邀请成员",
|
||||||
"user_team_leave_team": "离开团队",
|
"user_team_leave_team": "离开团队",
|
||||||
"user_team_leave_team_failed": "离开团队失败",
|
"user_team_leave_team_failed": "离开团队失败",
|
||||||
"waiting": "待接受"
|
"waiting": "待接受",
|
||||||
|
"permission_appCreate": "创建应用",
|
||||||
|
"permission_datasetCreate": "创建知识库",
|
||||||
|
"permission_apikeyCreate": "创建 API 密钥",
|
||||||
|
"permission_appCreate_tip": "可以在根目录创建应用,(文件夹下的创建权限由文件夹控制)",
|
||||||
|
"permission_datasetCreate_Tip": "可以在根目录创建知识库,(文件夹下的创建权限由文件夹控制)",
|
||||||
|
"permission_apikeyCreate_Tip": "可以创建全局的 APIKey",
|
||||||
|
"permission_manage": "管理员",
|
||||||
|
"permission_manage_tip": "可以管理成员、创建群组、管理所有群组、为群组和成员分配权限",
|
||||||
|
"log_login": "【{{name}}】登录了系统",
|
||||||
|
"log_create_invitation_link": "【{{name}}】创建了邀请链接【{{link}}】",
|
||||||
|
"log_join_team": "【{{name}}】通过邀请链接【{{link}}】加入团队",
|
||||||
|
"log_change_member_name": "【{{name}}】将成员【{{memberName}}】重命名为【{{newName}}】",
|
||||||
|
"log_kick_out_team": "【{{name}}】移除了成员【{{memberName}}】",
|
||||||
|
"log_create_department": "【{{name}}】创建了部门【{{departmentName}}】",
|
||||||
|
"log_change_department": "【{{name}}】更新了部门【{{departmentName}}】",
|
||||||
|
"log_delete_department": "【{{name}}】删除了部门【{{departmentName}}】",
|
||||||
|
"log_relocate_department": "【{{name}}】移动了部门【{{departmentName}}】",
|
||||||
|
"log_create_group": "【{{name}}】创建了群组【{{groupName}}】",
|
||||||
|
"log_delete_group": "【{{name}}】删除了群组【{{groupName}}】",
|
||||||
|
"log_assign_permission": "【{{name}}】更新了【{{objectName}}】的权限:[应用创建:【{{appCreate}}】, 知识库:【{{datasetCreate}}】, API密钥:【{{apiKeyCreate}}】, 管理:【{{manage}}】]"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -98,11 +98,9 @@
|
|||||||
"team.group.keep_admin": "保留管理员权限",
|
"team.group.keep_admin": "保留管理员权限",
|
||||||
"team.group.manage_member": "管理成员",
|
"team.group.manage_member": "管理成员",
|
||||||
"team.group.manage_tip": "可以管理成员、创建群组、管理所有群组、为群组和成员分配权限",
|
"team.group.manage_tip": "可以管理成员、创建群组、管理所有群组、为群组和成员分配权限",
|
||||||
|
"team.group.permission_tip": "单独配置权限的成员,将遵循个人权限配置,不再受群组权限影响。\n若成员在多个权限组,则该成员的权限取并集。",
|
||||||
"team.group.members": "成员",
|
"team.group.members": "成员",
|
||||||
"team.group.name": "群组名称",
|
"team.group.name": "群组名称",
|
||||||
"team.group.permission.manage": "管理员",
|
|
||||||
"team.group.permission.write": "工作台/知识库创建",
|
|
||||||
"team.group.permission_tip": "单独配置权限的成员,将遵循个人权限配置,不再受群组权限影响。\n若成员在多个权限组,则该成员的权限取并集。",
|
|
||||||
"team.group.role.admin": "管理员",
|
"team.group.role.admin": "管理员",
|
||||||
"team.group.role.member": "成员",
|
"team.group.role.member": "成员",
|
||||||
"team.group.role.owner": "所有者",
|
"team.group.role.owner": "所有者",
|
||||||
@@ -112,5 +110,6 @@
|
|||||||
"team.manage_collaborators": "管理协作者",
|
"team.manage_collaborators": "管理协作者",
|
||||||
"team.no_collaborators": "暂无协作者",
|
"team.no_collaborators": "暂无协作者",
|
||||||
"team.org.org": "部门",
|
"team.org.org": "部门",
|
||||||
"team.write_role_member": "可写权限"
|
"team.write_role_member": "可写权限",
|
||||||
|
"team.collaborator.added": "已添加"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,30 +3,30 @@
|
|||||||
"add_default_model": "新增預設模型",
|
"add_default_model": "新增預設模型",
|
||||||
"api_key": "API 金鑰",
|
"api_key": "API 金鑰",
|
||||||
"bills_and_invoices": "帳單與發票",
|
"bills_and_invoices": "帳單與發票",
|
||||||
"channel": "模型渠道",
|
"channel": "模型管道",
|
||||||
"config_model": "模型配置",
|
"config_model": "模型設定",
|
||||||
"confirm_logout": "確認登出登入?",
|
"confirm_logout": "確認登出登入?",
|
||||||
"create_channel": "新增頻道",
|
"create_channel": "新增頻道",
|
||||||
"create_model": "新增模型",
|
"create_model": "新增模型",
|
||||||
"custom_model": "自訂模型",
|
"custom_model": "自訂模型",
|
||||||
"default_model": "預設模型",
|
"default_model": "預設模型",
|
||||||
"default_model_config": "預設模型配置",
|
"default_model_config": "預設模型設定",
|
||||||
"logout": "登出",
|
"logout": "登出",
|
||||||
"model.active": "啟用",
|
"model.active": "啟用",
|
||||||
"model.alias": "別名",
|
"model.alias": "別名",
|
||||||
"model.alias_tip": "模型在系統中展示的名字,方便使用者理解",
|
"model.alias_tip": "模型在系統中展示的名字,方便使用者理解",
|
||||||
"model.censor_tip": "如果需要進行敏感校驗,則開啟該開關",
|
"model.censor_tip": "如果需要進行敏感校驗,則開啟該開關",
|
||||||
"model.charsPointsPrice": "模型綜合價格",
|
"model.charsPointsPrice": "模型綜合價格",
|
||||||
"model.charsPointsPrice_tip": "將模型輸入和輸出合併起來進行 Token 計費,語言模型如果單獨配置了輸入和輸出計費,則按輸入和輸出分別計算",
|
"model.charsPointsPrice_tip": "將模型輸入和輸出合併起來進行 Token 計費,語言模型如果單獨設定了輸入和輸出計費,則按輸入和輸出分別計算",
|
||||||
"model.custom_cq_prompt": "自訂問題分類提示詞",
|
"model.custom_cq_prompt": "自訂問題分類提示詞",
|
||||||
"model.custom_cq_prompt_tip": "覆蓋系統預設的問題分類提示詞,預設為:\n\"\"\"\n{{prompt}}\n\"\"\"",
|
"model.custom_cq_prompt_tip": "覆蓋系統預設的問題分類提示詞,預設為:\n\"\"\"\n{{prompt}}\n\"\"\"",
|
||||||
"model.custom_extract_prompt": "自訂內容提取提示詞",
|
"model.custom_extract_prompt": "自訂內容提取提示詞",
|
||||||
"model.custom_extract_prompt_tip": "覆蓋系統的提示詞,默認為:\n\"\"\"\n{{prompt}}\n\"\"\"",
|
"model.custom_extract_prompt_tip": "覆蓋系統的提示詞,預設為:\n\"\"\"\n{{prompt}}\n\"\"\"",
|
||||||
"model.dataset_process": "用於知識庫文件處理",
|
"model.dataset_process": "用於知識庫文件處理",
|
||||||
"model.defaultConfig": "額外 Body 參數",
|
"model.defaultConfig": "額外 Body 參數",
|
||||||
"model.defaultConfig_tip": "每次請求時候,都會攜帶該額外 Body 參數",
|
"model.defaultConfig_tip": "每次請求時候,都會攜帶該額外 Body 參數",
|
||||||
"model.default_config": "Body 額外字段",
|
"model.default_config": "Body 額外欄位",
|
||||||
"model.default_config_tip": "發起對話請求時候,合併該配置。例如:\n\"\"\"\n{\n \"temperature\": 1,\n \"max_tokens\": null\n}\n\"\"\"",
|
"model.default_config_tip": "發起對話請求時候,合併該設定。例如:\n\"\"\"\n{\n \"temperature\": 1,\n \"max_tokens\": null\n}\n\"\"\"",
|
||||||
"model.default_model": "預設模型",
|
"model.default_model": "預設模型",
|
||||||
"model.default_system_chat_prompt": "預設提示詞",
|
"model.default_system_chat_prompt": "預設提示詞",
|
||||||
"model.default_system_chat_prompt_tip": "模型對話時,都會攜帶該預設提示詞",
|
"model.default_system_chat_prompt_tip": "模型對話時,都會攜帶該預設提示詞",
|
||||||
@@ -34,35 +34,35 @@
|
|||||||
"model.default_token_tip": "索引模型預設文字分塊的長度,必須小於最大上文",
|
"model.default_token_tip": "索引模型預設文字分塊的長度,必須小於最大上文",
|
||||||
"model.delete_model_confirm": "確認刪除該模型?",
|
"model.delete_model_confirm": "確認刪除該模型?",
|
||||||
"model.edit_model": "模型參數編輯",
|
"model.edit_model": "模型參數編輯",
|
||||||
"model.function_call": "支援函數調用",
|
"model.function_call": "支援函式呼叫",
|
||||||
"model.function_call_tip": "如果模型支援函數調用,則開啟該開關。\n工具呼叫優先權更高。",
|
"model.function_call_tip": "如果模型支援函式呼叫,則開啟該開關。\n工具呼叫優先權更高。",
|
||||||
"model.input_price": "模型輸入價格",
|
"model.input_price": "模型輸入價格",
|
||||||
"model.input_price_tip": "語言模型輸入價格,如果配置了該項,則模型綜合價格會失效",
|
"model.input_price_tip": "語言模型輸入價格,如果設定了該項,則模型綜合價格會失效",
|
||||||
"model.json_config": "設定檔",
|
"model.json_config": "設定檔",
|
||||||
"model.json_config_confirm": "確認使用該配置進行覆蓋?",
|
"model.json_config_confirm": "確認使用該設定進行覆蓋?",
|
||||||
"model.json_config_tip": "透過設定檔設定模型,點選確認後,會使用輸入的配置進行全量覆蓋,請確保設定檔輸入正確。\n建議操作前,複製目前設定檔進行備份。",
|
"model.json_config_tip": "透過設定檔設定模型,點選確認後,會使用輸入的設定進行全量覆蓋,請確保設定檔輸入正確。\n建議操作前,複製目前設定檔進行備份。",
|
||||||
"model.max_quote": "知識庫最大引用",
|
"model.max_quote": "知識庫最大引用",
|
||||||
"model.max_temperature": "最大溫度",
|
"model.max_temperature": "最大溫度",
|
||||||
"model.model_id": "模型ID",
|
"model.model_id": "模型 ID",
|
||||||
"model.model_id_tip": "模型的唯一標識,也就是實際請求到服務商model 的值,需要與 OneAPI 頻道中的模型對應。",
|
"model.model_id_tip": "模型的唯一標識,也就是實際請求到服務商 model 的值,需要與 OneAPI 頻道中的模型對應。",
|
||||||
"model.normalization": "歸一化處理",
|
"model.normalization": "歸一化處理",
|
||||||
"model.normalization_tip": "如果Embedding API 未對向量值進行歸一化,可以啟用該開關,系統會進行歸一化處理。\n\n未歸一化的 API,表現為向量檢索得分會大於 1。",
|
"model.normalization_tip": "如果 Embedding API 未對向量值進行歸一化,可以啟用該開關,系統會進行歸一化處理。\n\n未歸一化的 API,表現為向量檢索得分會大於 1。",
|
||||||
"model.output_price": "模型輸出價格",
|
"model.output_price": "模型輸出價格",
|
||||||
"model.output_price_tip": "語言模型輸出價格,如果配置了該項,則模型綜合價格會失效",
|
"model.output_price_tip": "語言模型輸出價格,如果設定了該項,則模型綜合價格會失效",
|
||||||
"model.param_name": "參數名",
|
"model.param_name": "參數名稱",
|
||||||
"model.reasoning": "支持輸出思考",
|
"model.reasoning": "支援輸出思考",
|
||||||
"model.reasoning_tip": "例如 Deepseek-reasoner,可以輸出思考過程。",
|
"model.reasoning_tip": "例如 Deepseek-reasoner,可以輸出思考過程。",
|
||||||
"model.request_auth": "自訂請求 Key",
|
"model.request_auth": "自訂請求 Key",
|
||||||
"model.request_auth_tip": "向自訂請求地址發起請求時候,攜帶請求頭:Authorization: Bearer xxx 進行請求",
|
"model.request_auth_tip": "向自訂請求地址發起請求時候,攜帶請求頭:Authorization: Bearer xxx 進行請求",
|
||||||
"model.request_url": "自訂請求地址",
|
"model.request_url": "自訂請求地址",
|
||||||
"model.request_url_tip": "如果填寫該值,則會直接向該地址發起請求,不經過 OneAPI。\n需要遵循 OpenAI 的 API格式,並填寫完整請求地址,例如:\n\nLLM: {{host}}/v1/chat/completions\n\nEmbedding: {{host}}/v1/embeddings\n\nSTT: {{host}}/v1/audio/transcriptions\n\nTTS: {{host}}/v1/audio/speech\n\nRerank: {{host}}/v1/rerank",
|
"model.request_url_tip": "如果填寫該值,則會直接向該地址發起請求,不經過 OneAPI。\n需要遵循 OpenAI 的 API 格式,並填寫完整請求地址,例如:\n\nLLM: {{host}}/v1/chat/completions\n\nEmbedding: {{host}}/v1/embeddings\n\nSTT: {{host}}/v1/audio/transcriptions\n\nTTS: {{host}}/v1/audio/speech\n\nRerank: {{host}}/v1/rerank",
|
||||||
"model.response_format": "響應格式",
|
"model.response_format": "響應格式",
|
||||||
"model.show_stop_sign": "展示停止序列參數",
|
"model.show_stop_sign": "展示停止序列參數",
|
||||||
"model.show_top_p": "展示 Top-p 參數",
|
"model.show_top_p": "展示 Top-p 參數",
|
||||||
"model.test_model": "模型測試",
|
"model.test_model": "模型測試",
|
||||||
"model.tool_choice": "支援工具調用",
|
"model.tool_choice": "支援工具呼叫",
|
||||||
"model.tool_choice_tag": "工具調用",
|
"model.tool_choice_tag": "工具呼叫",
|
||||||
"model.tool_choice_tip": "如果該模型支援工具調用,則開啟該開關",
|
"model.tool_choice_tip": "如果該模型支援工具呼叫,則開啟該開關",
|
||||||
"model.used_in_classify": "用於問題分類",
|
"model.used_in_classify": "用於問題分類",
|
||||||
"model.used_in_extract_fields": "用於文字擷取",
|
"model.used_in_extract_fields": "用於文字擷取",
|
||||||
"model.used_in_tool_call": "用於工具呼叫節點",
|
"model.used_in_tool_call": "用於工具呼叫節點",
|
||||||
@@ -70,14 +70,14 @@
|
|||||||
"model.vision_tag": "視覺",
|
"model.vision_tag": "視覺",
|
||||||
"model.vision_tip": "如果模型支援圖片識別,則開啟該開關。",
|
"model.vision_tip": "如果模型支援圖片識別,則開啟該開關。",
|
||||||
"model.voices": "聲音角色",
|
"model.voices": "聲音角色",
|
||||||
"model.voices_tip": "透過一個數組配置多個,例如:\n\n[\n {\n \"label\": \"Alloy\",\n \"value\": \"alloy\"\n },\n {\n \"label\": \"Echo\",\n \"value\": \"echo\"\n }\n]",
|
"model.voices_tip": "透過一個陣列設定多個,例如:\n\n[\n {\n \"label\": \"Alloy\",\n \"value\": \"alloy\"\n },\n {\n \"label\": \"Echo\",\n \"value\": \"echo\"\n }\n]",
|
||||||
"model_provider": "模型提供者",
|
"model_provider": "模型提供者",
|
||||||
"notifications": "通知",
|
"notifications": "通知",
|
||||||
"personal_information": "個人資訊",
|
"personal_information": "個人資訊",
|
||||||
"personalization": "個人化",
|
"personalization": "個人化",
|
||||||
"promotion_records": "促銷記錄",
|
"promotion_records": "促銷記錄",
|
||||||
"reset_default": "恢復默認配置",
|
"reset_default": "恢復預設設定",
|
||||||
"team": "團隊管理",
|
"team": "團隊管理",
|
||||||
"third_party": "第三方账号",
|
"third_party": "第三方賬號",
|
||||||
"usage_records": "使用記錄"
|
"usage_records": "使用記錄"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
"back": "返回",
|
"back": "返回",
|
||||||
"bank_account": "開戶帳號",
|
"bank_account": "開戶帳號",
|
||||||
"bank_name": "開戶銀行",
|
"bank_name": "開戶銀行",
|
||||||
"bill_detail": "帳單詳情",
|
"bill_detail": "帳單詳細資訊",
|
||||||
"bill_record": "帳單記錄",
|
"bill_record": "帳單記錄",
|
||||||
"company_address": "公司地址",
|
"company_address": "公司地址",
|
||||||
"company_phone": "公司電話",
|
"company_phone": "公司電話",
|
||||||
@@ -12,15 +12,15 @@
|
|||||||
"contact_phone": "聯絡電話",
|
"contact_phone": "聯絡電話",
|
||||||
"contact_phone_void": "聯絡電話格式錯誤",
|
"contact_phone_void": "聯絡電話格式錯誤",
|
||||||
"default_header": "預設抬頭",
|
"default_header": "預設抬頭",
|
||||||
"detail": "詳情",
|
"detail": "詳細資訊",
|
||||||
"email_address": "郵件地址",
|
"email_address": "郵件地址",
|
||||||
"extra_ai_points": "AI 積分運算標準",
|
"extra_ai_points": "AI 積分運算標準",
|
||||||
"extra_dataset_size": "額外知識庫容量",
|
"extra_dataset_size": "額外知識庫容量",
|
||||||
"generation_time": "生成時間",
|
"generation_time": "生成時間",
|
||||||
"has_invoice": "是否已開票",
|
"has_invoice": "是否已開票",
|
||||||
"invoice_amount": "開票金額",
|
"invoice_amount": "開票金額",
|
||||||
"invoice_detail": "發票詳情",
|
"invoice_detail": "發票詳細資訊",
|
||||||
"invoice_sending_info": "發票將在 3-7 個工作天內發送至郵箱,請耐心等待",
|
"invoice_sending_info": "發票將在 3-7 個工作天內傳送至郵箱,請耐心等待",
|
||||||
"mm": "毫米",
|
"mm": "毫米",
|
||||||
"need_special_invoice": "是否需要專票",
|
"need_special_invoice": "是否需要專票",
|
||||||
"no": "否",
|
"no": "否",
|
||||||
@@ -31,8 +31,8 @@
|
|||||||
"organization_name": "組織名稱",
|
"organization_name": "組織名稱",
|
||||||
"payment_method": "支付方式",
|
"payment_method": "支付方式",
|
||||||
"save": "儲存",
|
"save": "儲存",
|
||||||
"save_failed": "保存異常",
|
"save_failed": "儲存異常",
|
||||||
"save_success": "保存成功",
|
"save_success": "儲存成功",
|
||||||
"status": "狀態",
|
"status": "狀態",
|
||||||
"submit_failed": "提交失敗",
|
"submit_failed": "提交失敗",
|
||||||
"submit_success": "提交成功",
|
"submit_success": "提交成功",
|
||||||
|
|||||||
@@ -28,10 +28,10 @@
|
|||||||
"exchange_success": "兌換成功",
|
"exchange_success": "兌換成功",
|
||||||
"expiration_time": "到期時間",
|
"expiration_time": "到期時間",
|
||||||
"expired": "已過期",
|
"expired": "已過期",
|
||||||
"general_info": "通用信息",
|
"general_info": "通用資訊",
|
||||||
"group": "群組",
|
"group": "群組",
|
||||||
"help_chatbot": "機器人助手",
|
"help_chatbot": "機器人助手",
|
||||||
"help_document": "幫助文檔",
|
"help_document": "幫助文件",
|
||||||
"knowledge_base_capacity": "知識庫容量",
|
"knowledge_base_capacity": "知識庫容量",
|
||||||
"manage": "管理",
|
"manage": "管理",
|
||||||
"member_name": "成員名",
|
"member_name": "成員名",
|
||||||
@@ -39,36 +39,36 @@
|
|||||||
"new_password": "新密碼",
|
"new_password": "新密碼",
|
||||||
"notification_receiving": "通知接收",
|
"notification_receiving": "通知接收",
|
||||||
"old_password": "舊密碼",
|
"old_password": "舊密碼",
|
||||||
"openai_account_configuration": "OpenAI 帳號配置",
|
"openai_account_configuration": "OpenAI 帳號設定",
|
||||||
"openai_account_setting_exception": "設定 OpenAI 帳號異常",
|
"openai_account_setting_exception": "設定 OpenAI 帳號異常",
|
||||||
"package_and_usage": "套餐與用量",
|
"package_and_usage": "套餐與用量",
|
||||||
"package_details": "套餐詳情",
|
"package_details": "套餐詳細資訊",
|
||||||
"package_expiry_time": "套餐到期時間",
|
"package_expiry_time": "套餐到期時間",
|
||||||
"package_usage_rules": "套餐使用規則:系統優先使用更進階的套餐,原未用完的套餐將延遲生效",
|
"package_usage_rules": "套餐使用規則:系統優先使用更進階的套餐,原未用完的套餐將延遲生效",
|
||||||
"password": "密碼",
|
"password": "密碼",
|
||||||
"password_mismatch": "密碼不一致: 兩次密碼不一致",
|
"password_mismatch": "密碼不一致:兩次密碼不一致",
|
||||||
"password_tip": "密碼至少 6 位,且至少包含兩種組合:數字、字母或特殊字符",
|
"password_tip": "密碼至少 6 位,且至少包含兩種組合:數字、字母或特殊字元",
|
||||||
"password_update_error": "修改密碼異常",
|
"password_update_error": "修改密碼異常",
|
||||||
"password_update_success": "修改密碼成功",
|
"password_update_success": "修改密碼成功",
|
||||||
"pending_usage": "待使用",
|
"pending_usage": "待使用",
|
||||||
"phone_label": "手機號",
|
"phone_label": "手機號",
|
||||||
"please_bind_notification_receiving_path": "請先綁定通知接收途徑",
|
"please_bind_notification_receiving_path": "請先綁定通知接收途徑",
|
||||||
"purchase_extra_package": "購買額外套餐",
|
"purchase_extra_package": "購買額外套餐",
|
||||||
"reminder_create_bound_notification_account": "提醒創建者綁定通知帳號",
|
"reminder_create_bound_notification_account": "提醒建立者綁定通知帳號",
|
||||||
"resource_usage": "資源用量",
|
"resource_usage": "資源用量",
|
||||||
"select_avatar": "點選選擇頭像",
|
"select_avatar": "點選選擇頭像",
|
||||||
"standard_package_and_extra_resource_package": "包含標準套餐與額外資源包",
|
"standard_package_and_extra_resource_package": "包含標準套餐與額外資源包",
|
||||||
"storage_capacity": "儲存量",
|
"storage_capacity": "儲存量",
|
||||||
"team_balance": "團隊餘額",
|
"team_balance": "團隊餘額",
|
||||||
"team_info": "團隊信息",
|
"team_info": "團隊資訊",
|
||||||
"token_validity_period": "積分有效期限一年",
|
"token_validity_period": "積分有效期限一年",
|
||||||
"tokens": "積分",
|
"tokens": "積分",
|
||||||
"type": "類型",
|
"type": "類型",
|
||||||
"unlimited": "無限制",
|
"unlimited": "無限制",
|
||||||
"update_password": "修改密碼",
|
"update_password": "修改密碼",
|
||||||
"update_success_tip": "更新數據成功",
|
"update_success_tip": "更新資料成功",
|
||||||
"upgrade_package": "升級套餐",
|
"upgrade_package": "升級套餐",
|
||||||
"usage_balance": "使用餘額: 使用餘額",
|
"usage_balance": "使用餘額:使用餘額",
|
||||||
"usage_balance_notice": "由於系統升級,原「自動續費從餘額扣款」模式取消,餘額儲值入口關閉。\n您的餘額可用於購買積分",
|
"usage_balance_notice": "由於系統升級,原「自動續費從餘額扣款」模式取消,餘額儲值入口關閉。\n您的餘額可用於購買積分",
|
||||||
"user_account": "帳號",
|
"user_account": "帳號",
|
||||||
"user_team_team_name": "團隊",
|
"user_team_team_name": "團隊",
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"notification_detail": "通知詳情",
|
"notification_detail": "通知詳細資訊",
|
||||||
"no_notifications": "暫無通知",
|
"no_notifications": "暫無通知",
|
||||||
"read": "已讀",
|
"read": "已讀",
|
||||||
"system": "官方",
|
"system": "官方",
|
||||||
|
|||||||
@@ -1,52 +1,52 @@
|
|||||||
{
|
{
|
||||||
"Hunyuan": "騰訊混元",
|
"Hunyuan": "騰訊混元",
|
||||||
"api_key": "API 密鑰",
|
"api_key": "API 金鑰",
|
||||||
"azure": "Azure",
|
"azure": "Azure",
|
||||||
"base_url": "代理地址",
|
"base_url": "代理地址",
|
||||||
"channel_name": "渠道名",
|
"channel_name": "管道名稱",
|
||||||
"channel_priority": "優先級",
|
"channel_priority": "優先順序",
|
||||||
"channel_priority_tip": "優先級越高的渠道,越容易被請求到",
|
"channel_priority_tip": "優先順序越高的管道,越容易被請求到",
|
||||||
"channel_status": "狀態",
|
"channel_status": "狀態",
|
||||||
"channel_status_auto_disabled": "自動禁用",
|
"channel_status_auto_disabled": "自動停用",
|
||||||
"channel_status_disabled": "禁用",
|
"channel_status_disabled": "停用",
|
||||||
"channel_status_enabled": "啟用",
|
"channel_status_enabled": "啟用",
|
||||||
"channel_status_unknown": "未知",
|
"channel_status_unknown": "未知",
|
||||||
"channel_type": "廠商",
|
"channel_type": "廠商",
|
||||||
"clear_model": "清空模型",
|
"clear_model": "清空模型",
|
||||||
"confirm_delete_channel": "確認刪除 【{{name}}】渠道?",
|
"confirm_delete_channel": "確認刪除【{{name}}】管道?",
|
||||||
"copy_model_id_success": "已復制模型id",
|
"copy_model_id_success": "已復制模型 id",
|
||||||
"create_channel": "新增渠道",
|
"create_channel": "新增管道",
|
||||||
"default_url": "默認地址",
|
"default_url": "預設地址",
|
||||||
"detail": "詳情",
|
"detail": "詳細資訊",
|
||||||
"edit_channel": "渠道配置",
|
"edit_channel": "管道設定",
|
||||||
"enable_channel": "啟用",
|
"enable_channel": "啟用",
|
||||||
"forbid_channel": "禁用",
|
"forbid_channel": "停用",
|
||||||
"key_type": "API key 格式:",
|
"key_type": "API key 格式:",
|
||||||
"log": "調用日誌",
|
"log": "呼叫日誌",
|
||||||
"log_detail": "日誌詳情",
|
"log_detail": "日誌詳細資訊",
|
||||||
"log_request_id_search": "根據 requestId 搜索",
|
"log_request_id_search": "根據 requestId 搜尋",
|
||||||
"log_status": "狀態",
|
"log_status": "狀態",
|
||||||
"mapping": "模型映射",
|
"mapping": "模型對映",
|
||||||
"mapping_tip": "需填寫一個有效 Json。\n可在向實際地址發送請求時,對模型進行映射。\n例如:\n{\n \n \"gpt-4o\": \"gpt-4o-test\"\n\n}\n\n當 FastGPT 請求 gpt-4o 模型時,會向實際地址發送 gpt-4o-test 的模型,而不是 gpt-4o。",
|
"mapping_tip": "需填寫一個有效 Json。\n可在向實際地址傳送請求時,對模型進行對映。\n例如:\n{\n \n \"gpt-4o\": \"gpt-4o-test\"\n\n}\n\n當 FastGPT 請求 gpt-4o 模型時,會向實際地址傳送 gpt-4o-test 的模型,而不是 gpt-4o。",
|
||||||
"maxToken_tip": "模型 max_tokens 參數,如果留空,則代表模型不支持該參數。",
|
"maxToken_tip": "模型 max_tokens 參數,如果留空,則代表模型不支援該參數。",
|
||||||
"max_temperature_tip": "模型 temperature 參數,不填則代表模型不支持 temperature 參數。",
|
"max_temperature_tip": "模型 temperature 參數,不填則代表模型不支援 temperature 參數。",
|
||||||
"model": "模型",
|
"model": "模型",
|
||||||
"model_name": "模型名",
|
"model_name": "模型名",
|
||||||
"model_test": "模型測試",
|
"model_test": "模型測試",
|
||||||
"model_tokens": "輸入/輸出 Tokens",
|
"model_tokens": "輸入/輸出 Tokens",
|
||||||
"request_at": "請求時間",
|
"request_at": "請求時間",
|
||||||
"request_duration": "請求時長: {{duration}}s",
|
"request_duration": "請求時長:{{duration}}s",
|
||||||
"retry_times": "重試次數",
|
"retry_times": "重試次數",
|
||||||
"running_test": "測試中",
|
"running_test": "測試中",
|
||||||
"search_model": "搜索模型",
|
"search_model": "搜尋模型",
|
||||||
"select_channel": "選擇渠道名",
|
"select_channel": "選擇管道名稱",
|
||||||
"select_model": "選擇模型",
|
"select_model": "選擇模型",
|
||||||
"select_model_placeholder": "選擇該渠道下可用的模型",
|
"select_model_placeholder": "選擇該管道下可用的模型",
|
||||||
"select_provider_placeholder": "搜索廠商",
|
"select_provider_placeholder": "搜尋廠商",
|
||||||
"selected_model_empty": "至少選擇一個模型",
|
"selected_model_empty": "至少選擇一個模型",
|
||||||
"start_test": "批量測試{{num}}個模型",
|
"start_test": "批次測試{{num}}個模型",
|
||||||
"test_failed": "有{{num}}個模型報錯",
|
"test_failed": "有{{num}}個模型報錯",
|
||||||
"vlm_model": "圖片理解模型",
|
"vlm_model": "圖片理解模型",
|
||||||
"vlm_model_tip": "用於知識庫中對文檔中的圖片進行額外的索引生成",
|
"vlm_model_tip": "用於知識庫中對文件中的圖片進行額外的索引生成",
|
||||||
"waiting_test": "等待測試"
|
"waiting_test": "等待測試"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
"copy_invite_link": "複製邀請連結",
|
"copy_invite_link": "複製邀請連結",
|
||||||
"earnings": "收益(¥)",
|
"earnings": "收益(¥)",
|
||||||
"invite_url": "邀請連結",
|
"invite_url": "邀請連結",
|
||||||
"invite_url_tip": "透過該連結註冊的好友將永久與你綁定,其儲值時你會獲得一定餘額獎勵。\n \n此外,好友使用手機號碼註冊時,你將立即獲得 5 元獎勵。\n \n獎勵會發送到您的預設團隊。",
|
"invite_url_tip": "透過該連結註冊的好友將永久與你綁定,其儲值時你會獲得一定餘額獎勵。\n \n此外,好友使用手機號碼註冊時,你將立即獲得 5 元獎勵。\n \n獎勵會傳送到您的預設團隊。",
|
||||||
"no_invite_records": "暫無邀請紀錄",
|
"no_invite_records": "暫無邀請紀錄",
|
||||||
"time": "時間",
|
"time": "時間",
|
||||||
"total_invited": "累計邀請人數",
|
"total_invited": "累計邀請人數",
|
||||||
|
|||||||
@@ -2,5 +2,5 @@
|
|||||||
"language": "語言",
|
"language": "語言",
|
||||||
"personalization": "個人化",
|
"personalization": "個人化",
|
||||||
"timezone": "時區",
|
"timezone": "時區",
|
||||||
"update_data_success": "更新數據成功"
|
"update_data_success": "更新資料成功"
|
||||||
}
|
}
|
||||||
@@ -1,28 +1,34 @@
|
|||||||
{
|
{
|
||||||
"1person": "1人",
|
"1person": "1 人",
|
||||||
"1year": "1年",
|
"1year": "1 年",
|
||||||
"30mins": "30分鐘",
|
"30mins": "30 分鐘",
|
||||||
"7days": "7天",
|
"7days": "7 天",
|
||||||
"accept": "接受",
|
"accept": "接受",
|
||||||
"action": "操作",
|
"action": "操作",
|
||||||
|
"assign_permission": "權限變更",
|
||||||
|
"change_department_name": "部門編輯",
|
||||||
|
"change_member_name": "成員改名",
|
||||||
"confirm_delete_group": "確認刪除群組?",
|
"confirm_delete_group": "確認刪除群組?",
|
||||||
"confirm_delete_member": "確認刪除成員?",
|
"confirm_delete_member": "確認刪除成員?",
|
||||||
"confirm_delete_org": "確認刪除該部門?",
|
"confirm_delete_org": "確認刪除該部門?",
|
||||||
"confirm_forbidden": "確認停用",
|
"confirm_forbidden": "確認停用",
|
||||||
"confirm_leave_team": "確認離開該團隊? \n退出後,您在該團隊所有的資源轉讓給團隊所有者。",
|
"confirm_leave_team": "確認離開該團隊? \n結束後,您在該團隊所有的資源轉讓給團隊所有者。",
|
||||||
"copy_link": "複製連結",
|
"copy_link": "複製連結",
|
||||||
|
"create_department": "創建子部門",
|
||||||
"create_group": "建立群組",
|
"create_group": "建立群組",
|
||||||
"create_invitation_link": "建立邀請連結",
|
"create_invitation_link": "建立邀請連結",
|
||||||
"create_org": "創建部門",
|
"create_org": "建立部門",
|
||||||
"create_sub_org": "創建子部門",
|
"create_sub_org": "建立子部門",
|
||||||
"delete": "刪除",
|
"delete": "刪除",
|
||||||
|
"delete_department": "刪除子部門",
|
||||||
|
"delete_group": "刪除群組",
|
||||||
"delete_org": "刪除部門",
|
"delete_org": "刪除部門",
|
||||||
"edit_info": "編輯訊息",
|
"edit_info": "編輯訊息",
|
||||||
"edit_member": "編輯用戶",
|
"edit_member": "編輯使用者",
|
||||||
"edit_member_tip": "成員名",
|
"edit_member_tip": "成員名",
|
||||||
"edit_org_info": "編輯部門資訊",
|
"edit_org_info": "編輯部門資訊",
|
||||||
"expires": "過期時間",
|
"expires": "過期時間",
|
||||||
"forbid_hint": "停用後,該邀請連結將失效。 該操作不可撤銷,是否確認停用?",
|
"forbid_hint": "停用後,該邀請連結將失效。該操作不可撤銷,是否確認停用?",
|
||||||
"forbid_success": "停用成功",
|
"forbid_success": "停用成功",
|
||||||
"forbidden": "停用",
|
"forbidden": "停用",
|
||||||
"group": "群組",
|
"group": "群組",
|
||||||
@@ -32,26 +38,56 @@
|
|||||||
"has_invited": "已邀請",
|
"has_invited": "已邀請",
|
||||||
"ignore": "忽略",
|
"ignore": "忽略",
|
||||||
"invitation_copy_link": "【{{systemName}}】 {{userName}} 邀請您加入{{teamName}}團隊,連結:{{url}}",
|
"invitation_copy_link": "【{{systemName}}】 {{userName}} 邀請您加入{{teamName}}團隊,連結:{{url}}",
|
||||||
"invitation_link_auto_clean_hint": "已失效連結將在30天後自動清理",
|
"invitation_link_auto_clean_hint": "已失效連結將在 30 天後自動清理",
|
||||||
"invitation_link_description": "連結描述",
|
"invitation_link_description": "連結描述",
|
||||||
"invitation_link_list": "連結列表",
|
"invitation_link_list": "連結列表",
|
||||||
"invite_member": "邀請成員",
|
"invite_member": "邀請成員",
|
||||||
"invited": "已邀請",
|
"invited": "已邀請",
|
||||||
|
"join_team": "加入團隊",
|
||||||
|
"kick_out_team": "移除成員",
|
||||||
"label_sync": "標籤同步",
|
"label_sync": "標籤同步",
|
||||||
"leave_team_failed": "離開團隊異常",
|
"leave_team_failed": "離開團隊異常",
|
||||||
|
"log_assign_permission": "【{{name}}】更新了【{{objectName}}】的權限:[應用創建:【{{appCreate}}】, 知識庫:【{{datasetCreate}}】, API密鑰:【{{apiKeyCreate}}】, 管理:【{{manage}}】]",
|
||||||
|
"log_change_department": "【{{name}}】更新了部門【{{departmentName}}】",
|
||||||
|
"log_change_member_name": "【{{name}}】將成員【{{memberName}}】重命名為【{{newName}}】",
|
||||||
|
"log_create_department": "【{{name}}】創建了部門【{{departmentName}}】",
|
||||||
|
"log_create_group": "【{{name}}】創建了群組【{{groupName}}】",
|
||||||
|
"log_create_invitation_link": "【{{name}}】創建了邀請鏈接【{{link}}】",
|
||||||
|
"log_delete_department": "{{name}} 刪除了部門 {{departmentName}}",
|
||||||
|
"log_delete_group": "{{name}} 刪除了群組 {{groupName}}",
|
||||||
|
"log_details": "詳情",
|
||||||
|
"log_join_team": "【{{name}}】通過邀請鏈接【{{link}}】加入團隊",
|
||||||
|
"log_kick_out_team": "{{name}} 移除了成員 {{memberName}}",
|
||||||
|
"log_login": "【{{name}}】登錄了系統",
|
||||||
|
"log_relocate_department": "【{{name}}】移動了部門【{{departmentName}}】",
|
||||||
|
"log_time": "操作時間",
|
||||||
|
"log_type": "操作類型",
|
||||||
|
"log_user": "操作人員",
|
||||||
|
"login": "登入",
|
||||||
"manage_member": "管理成員",
|
"manage_member": "管理成員",
|
||||||
"member": "成員",
|
"member": "成員",
|
||||||
"member_group": "所屬成員組",
|
"member_group": "所屬成員組",
|
||||||
"move_member": "移動成員",
|
"move_member": "移動成員",
|
||||||
"move_org": "行動部門",
|
"move_org": "行動部門",
|
||||||
|
"operation_log": "紀錄",
|
||||||
"org": "組織",
|
"org": "組織",
|
||||||
"org_description": "介紹",
|
"org_description": "介紹",
|
||||||
"org_name": "部門名稱",
|
"org_name": "部門名稱",
|
||||||
"owner": "擁有者",
|
"owner": "擁有者",
|
||||||
"permission": "權限",
|
"permission": "權限",
|
||||||
|
"permission_apikeyCreate": "建立 API 密鑰",
|
||||||
|
"permission_apikeyCreate_Tip": "可以建立全域的 APIKey",
|
||||||
|
"permission_appCreate": "建立應用程式",
|
||||||
|
"permission_appCreate_tip": "可以在根目錄建立應用程式,(資料夾下的建立權限由資料夾控制)",
|
||||||
|
"permission_datasetCreate": "建立知識庫",
|
||||||
|
"permission_datasetCreate_Tip": "可以在根目錄建立知識庫,(資料夾下的建立權限由資料夾控制)",
|
||||||
|
"permission_manage": "管理員",
|
||||||
|
"permission_manage_tip": "可以管理成員、建立群組、管理所有群組、為群組和成員分配權限",
|
||||||
|
"relocate_department": "部門移動",
|
||||||
"remark": "備註",
|
"remark": "備註",
|
||||||
"remove_tip": "確認將 {{username}} 移出團隊?",
|
"remove_tip": "確認將 {{username}} 移出團隊?",
|
||||||
"retain_admin_permissions": "保留管理員權限",
|
"retain_admin_permissions": "保留管理員權限",
|
||||||
|
"search_log": "搜索日誌",
|
||||||
"search_member_group_name": "搜尋成員/群組名稱",
|
"search_member_group_name": "搜尋成員/群組名稱",
|
||||||
"total_team_members": "共 {{amount}} 名成員",
|
"total_team_members": "共 {{amount}} 名成員",
|
||||||
"transfer_ownership": "轉讓所有者",
|
"transfer_ownership": "轉讓所有者",
|
||||||
|
|||||||
@@ -1,16 +1,16 @@
|
|||||||
{
|
{
|
||||||
"configured": "已配置",
|
"configured": "已設定",
|
||||||
"error.no_permission": "請聯繫管理員配置",
|
"error.no_permission": "請聯絡管理員設定",
|
||||||
"laf_account": "af 帳號",
|
"laf_account": "af 帳號",
|
||||||
"no_intro": "暫無說明",
|
"no_intro": "暫無說明",
|
||||||
"not_configured": "未配置",
|
"not_configured": "未設定",
|
||||||
"open_api_notice": "可以填寫 OpenAI/OneAPI 的相關金鑰。\n如果你填寫了該內容,在線上平台使用【 AI 對話】、【問題分類】和【內容提取】將會走你填寫的 Key,不會計費用。\n請注意你的 Key 是否有存取對應模型的權限。 \nGPT 模型可以選擇 FastAI 。",
|
"open_api_notice": "可以填寫 OpenAI/OneAPI 的相關金鑰。\n如果你填寫了該內容,在線上平臺使用【AI 對話】、【問題分類】和【內容提取】將會走你填寫的 Key,不會計費用。\n請注意你的 Key 是否有存取對應模型的權限。 \nGPT 模型可以選擇 FastAI。",
|
||||||
"openai_account_configuration": "OpenAI/OneAPI 帳號",
|
"openai_account_configuration": "OpenAI/OneAPI 帳號",
|
||||||
"request_address_notice": "請求地址,預設為 openai 官方。可填中轉位址,未自動補全 \"v1\"",
|
"request_address_notice": "請求地址,預設為 openai 官方。可填中轉位址,未自動補全 \"v1\"",
|
||||||
"third_party_account": "第三方帳號",
|
"third_party_account": "第三方帳號",
|
||||||
"third_party_account_desc": "管理員可以在這裡配置第三方帳號或變量,該帳號將被團隊所有人使用",
|
"third_party_account_desc": "管理員可以在這裡設定第三方帳號或變數,該帳號將被團隊所有人使用",
|
||||||
"unavailable": "取得使用量異常",
|
"unavailable": "取得使用量異常",
|
||||||
"usage": "使用量:",
|
"usage": "使用量:",
|
||||||
"value_not_return_tip": "參數配置後,不會再次返回前端,無需洩漏給其他成員",
|
"value_not_return_tip": "參數設定後,不會再次返回前端,無需洩漏給其他成員",
|
||||||
"value_placeholder": "輸入參數值。\n輸入空值表示刪除該配置。"
|
"value_placeholder": "輸入參數值。\n輸入空值表示刪除該設定。"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,17 +4,17 @@
|
|||||||
"app_name": "應用程式名",
|
"app_name": "應用程式名",
|
||||||
"auto_index": "索引增強",
|
"auto_index": "索引增強",
|
||||||
"billing_module": "扣費模組",
|
"billing_module": "扣費模組",
|
||||||
"confirm_export": "共篩選出 {{total}} 條數據,是否確認導出?",
|
"confirm_export": "共篩選出 {{total}} 條資料,是否確認匯出?",
|
||||||
"current_filter_conditions": "當前篩選條件:",
|
"current_filter_conditions": "目前篩選條件:",
|
||||||
"dashboard": "儀表板",
|
"dashboard": "儀表板",
|
||||||
"details": "詳情",
|
"details": "詳細資訊",
|
||||||
"dingtalk": "釘釘",
|
"dingtalk": "釘釘",
|
||||||
"duration_seconds": "時長(秒)",
|
"duration_seconds": "時長(秒)",
|
||||||
"embedding_index": "索引生成",
|
"embedding_index": "索引生成",
|
||||||
"every_day": "天",
|
"every_day": "天",
|
||||||
"every_month": "月",
|
"every_month": "月",
|
||||||
"export_confirm": "導出確認",
|
"export_confirm": "匯出確認",
|
||||||
"export_confirm_tip": "當前共 {{total}} 筆使用記錄,確認導出?",
|
"export_confirm_tip": "目前共 {{total}} 筆使用記錄,確認匯出?",
|
||||||
"export_title": "時間,成員,類型,項目名,AI 積分消耗",
|
"export_title": "時間,成員,類型,項目名,AI 積分消耗",
|
||||||
"feishu": "飛書",
|
"feishu": "飛書",
|
||||||
"generation_time": "生成時間",
|
"generation_time": "生成時間",
|
||||||
@@ -42,7 +42,7 @@
|
|||||||
"total_points": "AI 積分消耗",
|
"total_points": "AI 積分消耗",
|
||||||
"total_points_consumed": "AI 積分消耗",
|
"total_points_consumed": "AI 積分消耗",
|
||||||
"total_usage": "總消耗",
|
"total_usage": "總消耗",
|
||||||
"usage_detail": "使用詳情",
|
"usage_detail": "使用詳細資訊",
|
||||||
"user_type": "類型",
|
"user_type": "類型",
|
||||||
"wecom": "企業微信"
|
"wecom": "企業微信"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,16 +3,16 @@
|
|||||||
"Run": "執行",
|
"Run": "執行",
|
||||||
"Team Tags Set": "團隊標籤",
|
"Team Tags Set": "團隊標籤",
|
||||||
"Team_Tags": "團隊標籤",
|
"Team_Tags": "團隊標籤",
|
||||||
"ai_point_price": "AI積分計費",
|
"ai_point_price": "AI 積分計費",
|
||||||
"ai_settings": "AI 設定",
|
"ai_settings": "AI 設定",
|
||||||
"all_apps": "所有應用程式",
|
"all_apps": "所有應用程式",
|
||||||
"app.Version name": "版本名稱",
|
"app.Version name": "版本名稱",
|
||||||
"app.error.publish_unExist_app": "發布失敗,請檢查工具調用是否正常",
|
"app.error.publish_unExist_app": "發布失敗,請檢查工具呼叫是否正常",
|
||||||
"app.error.unExist_app": "部分組件缺失,請刪除",
|
"app.error.unExist_app": "部分元件遺失,請刪除",
|
||||||
"app.modules.click to update": "點選更新",
|
"app.modules.click to update": "點選更新",
|
||||||
"app.modules.has new version": "有新版本",
|
"app.modules.has new version": "有新版本",
|
||||||
"app.modules.not_found": "組件缺失",
|
"app.modules.not_found": "元件遺失",
|
||||||
"app.modules.not_found_tips": "系統內無法查找到該組件,請刪除,否則流程無法正常運行",
|
"app.modules.not_found_tips": "系統內無法查詢到該元件,請刪除,否則流程無法正常運作",
|
||||||
"app.version_current": "目前版本",
|
"app.version_current": "目前版本",
|
||||||
"app.version_initial": "初始版本",
|
"app.version_initial": "初始版本",
|
||||||
"app.version_name_tips": "版本名稱不能空白",
|
"app.version_name_tips": "版本名稱不能空白",
|
||||||
@@ -20,23 +20,23 @@
|
|||||||
"app.version_publish_tips": "此版本將儲存至團隊雲端,同步給整個團隊,同時更新所有發布通道的應用程式版本",
|
"app.version_publish_tips": "此版本將儲存至團隊雲端,同步給整個團隊,同時更新所有發布通道的應用程式版本",
|
||||||
"app_detail": "應用程式詳細資訊",
|
"app_detail": "應用程式詳細資訊",
|
||||||
"auto_execute": "自動執行",
|
"auto_execute": "自動執行",
|
||||||
"auto_execute_default_prompt_placeholder": "自動執行時,發送的預設問題",
|
"auto_execute_default_prompt_placeholder": "自動執行時,傳送的預設問題",
|
||||||
"auto_execute_tip": "開啟後,使用者進入對話式介面將自動觸發工作流程。\n執行順序:1、對話開場白;2、全域變數;3、自動執行。",
|
"auto_execute_tip": "開啟後,使用者進入對話式介面將自動觸發工作流程。\n執行順序:1、對話開場白;2、全域變數;3、自動執行。",
|
||||||
"auto_save": "自動儲存",
|
"auto_save": "自動儲存",
|
||||||
"chat_debug": "聊天預覽",
|
"chat_debug": "聊天預覽",
|
||||||
"chat_logs": "對話紀錄",
|
"chat_logs": "對話紀錄",
|
||||||
"chat_logs_tips": "紀錄會記錄此應用程式的線上、分享和 API(需填寫 chatId)對話紀錄",
|
"chat_logs_tips": "紀錄會記錄此應用程式的線上、分享和 API(需填寫 chatId)對話紀錄",
|
||||||
"config_ai_model_params": "點選配置 AI 模型相關屬性",
|
"config_ai_model_params": "點選設定 AI 模型相關屬性",
|
||||||
"config_file_upload": "點選設定檔案上傳規則",
|
"config_file_upload": "點選設定檔案上傳規則",
|
||||||
"config_question_guide": "配置猜你想問",
|
"config_question_guide": "設定猜你想問",
|
||||||
"confirm_copy_app_tip": "系統將為您建立一個相同設定的應用程式,但權限不會複製,請確認!",
|
"confirm_copy_app_tip": "系統將為您建立一個相同設定的應用程式,但權限不會複製,請確認!",
|
||||||
"confirm_del_app_tip": "確認刪除【{{name}}】及其所有聊天紀錄?",
|
"confirm_del_app_tip": "確認刪除【{{name}}】及其所有聊天紀錄?",
|
||||||
"confirm_delete_folder_tip": "確認刪除這個資料夾?將會刪除它底下所有應用程式及對應的對話紀錄,請確認!",
|
"confirm_delete_folder_tip": "確認刪除這個資料夾?將會刪除它底下所有應用程式及對應的對話紀錄,請確認!",
|
||||||
"copy_one_app": "建立副本",
|
"copy_one_app": "建立副本",
|
||||||
"core.app.QG.Switch": "啟用猜你想問",
|
"core.app.QG.Switch": "啟用猜你想問",
|
||||||
"core.dataset.import.Custom prompt": "自訂提示詞",
|
"core.dataset.import.Custom prompt": "自訂提示詞",
|
||||||
"create_by_curl": "從 CURL 創建",
|
"create_by_curl": "從 CURL 建立",
|
||||||
"create_by_template": "從模板創建",
|
"create_by_template": "從範本建立",
|
||||||
"create_copy_success": "建立副本成功",
|
"create_copy_success": "建立副本成功",
|
||||||
"create_empty_app": "建立空白應用程式",
|
"create_empty_app": "建立空白應用程式",
|
||||||
"create_empty_plugin": "建立空白外掛",
|
"create_empty_plugin": "建立空白外掛",
|
||||||
@@ -74,22 +74,22 @@
|
|||||||
"interval.4_hours": "每 4 小時",
|
"interval.4_hours": "每 4 小時",
|
||||||
"interval.6_hours": "每 6 小時",
|
"interval.6_hours": "每 6 小時",
|
||||||
"interval.per_hour": "每小時",
|
"interval.per_hour": "每小時",
|
||||||
"intro": "FastGPT 是一個基於大型語言模型的知識庫平臺,提供開箱即用的資料處理、向量檢索和視覺化 AI 工作流程編排等功能,讓您可以輕鬆開發和部署複雜的問答系統,而無需繁瑣的設定或配置。",
|
"intro": "FastGPT 是一個基於大型語言模型的知識庫平臺,提供開箱即用的資料處理、向量檢索和視覺化 AI 工作流程編排等功能,讓您可以輕鬆開發和部署複雜的問答系統,而無需繁瑣的設定或設定。",
|
||||||
"invalid_json_format": "JSON 格式錯誤",
|
"invalid_json_format": "JSON 格式錯誤",
|
||||||
"llm_not_support_vision": "這個模型不支援圖片辨識",
|
"llm_not_support_vision": "這個模型不支援圖片辨識",
|
||||||
"llm_use_vision": "圖片辨識",
|
"llm_use_vision": "圖片辨識",
|
||||||
"llm_use_vision_tip": "點選模型選擇後,可以看到模型是否支援圖片辨識以及控制是否啟用圖片辨識的功能。啟用圖片辨識後,模型會讀取檔案連結中的圖片內容,並且如果使用者問題少於 500 字,會自動解析使用者問題中的圖片。",
|
"llm_use_vision_tip": "點選模型選擇後,可以看到模型是否支援圖片辨識以及控制是否啟用圖片辨識的功能。啟用圖片辨識後,模型會讀取檔案連結中的圖片內容,並且如果使用者問題少於 500 字,會自動解析使用者問題中的圖片。",
|
||||||
"logs_chat_user": "使用者",
|
"logs_chat_user": "使用者",
|
||||||
"logs_empty": "還沒有紀錄喔~",
|
"logs_empty": "還沒有紀錄喔~",
|
||||||
"logs_export_confirm_tip": "當前共 {{total}} 條對話記錄,確認導出?",
|
"logs_export_confirm_tip": "目前共 {{total}} 條對話記錄,確認匯出?",
|
||||||
"logs_export_title": "時間,來源,使用者,聯繫方式,標題,消息總數,用戶贊同反饋,用戶反對反饋,自定義反饋,標註答案,對話詳情",
|
"logs_export_title": "時間,來源,使用者,聯絡方式,標題,訊息總數,使用者贊同回饋,使用者反對回饋,自定義回饋,標註答案,對話詳細資訊",
|
||||||
"logs_message_total": "訊息總數",
|
"logs_message_total": "訊息總數",
|
||||||
"logs_source": "来源",
|
"logs_source": "來源",
|
||||||
"logs_title": "標題",
|
"logs_title": "標題",
|
||||||
"look_ai_point_price": "查看所有模型計費標準",
|
"look_ai_point_price": "檢視所有模型計費標準",
|
||||||
"mark_count": "標記答案數量",
|
"mark_count": "標記答案數量",
|
||||||
"max_histories_number": "記憶輪數",
|
"max_histories_number": "記憶輪數",
|
||||||
"max_histories_number_tip": "模型最多攜帶多少輪對話進入記憶中,如果記憶超出模型上下文,系統會強制截斷。\n所以儘管配置 30 輪對話,實際運行時候,不一定會達到 30 輪。",
|
"max_histories_number_tip": "模型最多攜帶多少輪對話進入記憶中,如果記憶超出模型上下文,系統會強制截斷。\n所以儘管設定 30 輪對話,實際運作時候,不一定會達到 30 輪。",
|
||||||
"max_tokens": "回覆上限",
|
"max_tokens": "回覆上限",
|
||||||
"module.Custom Title Tip": "這個標題會顯示在對話過程中",
|
"module.Custom Title Tip": "這個標題會顯示在對話過程中",
|
||||||
"module.No Modules": "找不到外掛",
|
"module.No Modules": "找不到外掛",
|
||||||
@@ -104,10 +104,10 @@
|
|||||||
"open_auto_execute": "啟用自動執行",
|
"open_auto_execute": "啟用自動執行",
|
||||||
"open_vision_function_tip": "有圖示開關的模型即擁有圖片辨識功能。若開啟,模型會解析檔案連結中的圖片,並自動解析使用者問題中的圖片(使用者問題 ≤ 500 字時生效)。",
|
"open_vision_function_tip": "有圖示開關的模型即擁有圖片辨識功能。若開啟,模型會解析檔案連結中的圖片,並自動解析使用者問題中的圖片(使用者問題 ≤ 500 字時生效)。",
|
||||||
"or_drag_JSON": "或拖曳 JSON 檔案",
|
"or_drag_JSON": "或拖曳 JSON 檔案",
|
||||||
"paste_config_or_drag": "貼上配置或拖入 JSON 文件",
|
"paste_config_or_drag": "貼上設定或拖入 JSON 文件",
|
||||||
"pdf_enhance_parse": "PDF增強解析",
|
"pdf_enhance_parse": "PDF 增強解析",
|
||||||
"pdf_enhance_parse_price": "{{price}}積分/頁",
|
"pdf_enhance_parse_price": "{{price}}積分/頁",
|
||||||
"pdf_enhance_parse_tips": "調用 PDF 識別模型進行解析,可以將其轉換成 Markdown 並保留文檔中的圖片,同時也可以對掃描件進行識別,識別時間較長。",
|
"pdf_enhance_parse_tips": "呼叫 PDF 識別模型進行解析,可以將其轉換成 Markdown 並保留文件中的圖片,同時也可以對掃描件進行識別,識別時間較長。",
|
||||||
"permission.des.manage": "在寫入權限基礎上,可以設定發布通道、檢視對話紀錄、分配這個應用程式的權限",
|
"permission.des.manage": "在寫入權限基礎上,可以設定發布通道、檢視對話紀錄、分配這個應用程式的權限",
|
||||||
"permission.des.read": "可以使用這個應用程式進行對話",
|
"permission.des.read": "可以使用這個應用程式進行對話",
|
||||||
"permission.des.write": "可以檢視和編輯應用程式",
|
"permission.des.write": "可以檢視和編輯應用程式",
|
||||||
@@ -120,16 +120,16 @@
|
|||||||
"publish_success": "發布成功",
|
"publish_success": "發布成功",
|
||||||
"question_guide_tip": "對話結束後,會為你產生 3 個引導性問題。",
|
"question_guide_tip": "對話結束後,會為你產生 3 個引導性問題。",
|
||||||
"reasoning_response": "輸出思考",
|
"reasoning_response": "輸出思考",
|
||||||
"response_format": "回复格式",
|
"response_format": "回覆格式",
|
||||||
"saved_success": "保存成功!\n如需在外部使用該版本,請點擊“儲存並發布”",
|
"saved_success": "儲存成功!\n如需在外部使用該版本,請點選“儲存並發布”",
|
||||||
"search_app": "搜尋應用程式",
|
"search_app": "搜尋應用程式",
|
||||||
"setting_app": "應用程式設定",
|
"setting_app": "應用程式設定",
|
||||||
"setting_plugin": "外掛設定",
|
"setting_plugin": "外掛設定",
|
||||||
"show_top_p_tip": "用溫度採樣的替代方法,稱為Nucleus採樣,該模型考慮了具有TOP_P概率質量質量的令牌的結果。\n因此,0.1表示僅考慮包含最高概率質量的令牌。\n默認為 1。",
|
"show_top_p_tip": "用溫度取樣的替代方法,稱為 Nucleus 取樣,該模型考慮了具有 TOP_P 機率質量質量的令牌的結果。\n因此,0.1 表示僅考慮包含最高機率質量的令牌。\n預設為 1。",
|
||||||
"simple_tool_tips": "該插件含有特殊輸入,暫不支持被簡易應用調用",
|
"simple_tool_tips": "該外掛含有特殊輸入,暫不支援被簡易應用呼叫",
|
||||||
"source_updateTime": "更新時間",
|
"source_updateTime": "更新時間",
|
||||||
"stop_sign": "停止序列",
|
"stop_sign": "停止序列",
|
||||||
"stop_sign_placeholder": "多個序列號通過 | 隔開,例如:aaa|stop",
|
"stop_sign_placeholder": "多個序列號透過 | 隔開,例如:aaa|stop",
|
||||||
"stream_response": "流輸出",
|
"stream_response": "流輸出",
|
||||||
"stream_response_tip": "關閉該開關,可以強制模型使用非流模式,並且不會直接進行內容輸出。\n可在 AI 回覆的輸出中,取得本次模型輸出的內容進行二次處理。",
|
"stream_response_tip": "關閉該開關,可以強制模型使用非流模式,並且不會直接進行內容輸出。\n可在 AI 回覆的輸出中,取得本次模型輸出的內容進行二次處理。",
|
||||||
"temperature": "溫度",
|
"temperature": "溫度",
|
||||||
@@ -152,7 +152,7 @@
|
|||||||
"templateMarket.templateTags.Roleplay": "角色扮演",
|
"templateMarket.templateTags.Roleplay": "角色扮演",
|
||||||
"templateMarket.templateTags.Web_search": "網路搜尋",
|
"templateMarket.templateTags.Web_search": "網路搜尋",
|
||||||
"templateMarket.templateTags.Writing": "文字創作",
|
"templateMarket.templateTags.Writing": "文字創作",
|
||||||
"templateMarket.template_guide": "模板說明",
|
"templateMarket.template_guide": "範本說明",
|
||||||
"template_market": "範本市集",
|
"template_market": "範本市集",
|
||||||
"template_market_description": "在範本市集探索更多玩法,設定教學與使用指引,帶您理解並上手各種應用程式",
|
"template_market_description": "在範本市集探索更多玩法,設定教學與使用指引,帶您理解並上手各種應用程式",
|
||||||
"template_market_empty_data": "找不到合適的範本",
|
"template_market_empty_data": "找不到合適的範本",
|
||||||
@@ -162,7 +162,7 @@
|
|||||||
"transition_to_workflow_create_new_placeholder": "建立新的應用程式,而不是修改目前應用程式",
|
"transition_to_workflow_create_new_placeholder": "建立新的應用程式,而不是修改目前應用程式",
|
||||||
"transition_to_workflow_create_new_tip": "轉換成工作流程後,將無法轉換回簡易模式,請確認!",
|
"transition_to_workflow_create_new_tip": "轉換成工作流程後,將無法轉換回簡易模式,請確認!",
|
||||||
"tts_ai_model": "使用語音合成模型",
|
"tts_ai_model": "使用語音合成模型",
|
||||||
"tts_browser": "瀏覽器自帶(免費)",
|
"tts_browser": "瀏覽器自帶 (免費)",
|
||||||
"tts_close": "關閉",
|
"tts_close": "關閉",
|
||||||
"type.All": "全部",
|
"type.All": "全部",
|
||||||
"type.Create http plugin tip": "透過 OpenAPI Schema 批次建立外掛,相容 GPTs 格式",
|
"type.Create http plugin tip": "透過 OpenAPI Schema 批次建立外掛,相容 GPTs 格式",
|
||||||
@@ -173,7 +173,7 @@
|
|||||||
"type.Create workflow bot": "建立工作流程",
|
"type.Create workflow bot": "建立工作流程",
|
||||||
"type.Create workflow tip": "透過低程式碼的方式,建立邏輯複雜的多輪對話 AI 應用程式,建議進階使用者使用",
|
"type.Create workflow tip": "透過低程式碼的方式,建立邏輯複雜的多輪對話 AI 應用程式,建議進階使用者使用",
|
||||||
"type.Http plugin": "HTTP 外掛",
|
"type.Http plugin": "HTTP 外掛",
|
||||||
"type.Import from json": "導入 JSON 配置",
|
"type.Import from json": "匯入 JSON 設定",
|
||||||
"type.Import from json tip": "透過 JSON 設定文件,直接建立應用",
|
"type.Import from json tip": "透過 JSON 設定文件,直接建立應用",
|
||||||
"type.Plugin": "外掛",
|
"type.Plugin": "外掛",
|
||||||
"type.Simple bot": "簡易應用程式",
|
"type.Simple bot": "簡易應用程式",
|
||||||
|
|||||||
@@ -5,20 +5,20 @@
|
|||||||
"ai_reasoning": "思考過程",
|
"ai_reasoning": "思考過程",
|
||||||
"back_to_text": "返回輸入",
|
"back_to_text": "返回輸入",
|
||||||
"chat.quote.No Data": "找不到該文件",
|
"chat.quote.No Data": "找不到該文件",
|
||||||
"chat.quote.deleted": "該數據已被刪除~",
|
"chat.quote.deleted": "該資料已被刪除~",
|
||||||
"chat_history": "對話紀錄",
|
"chat_history": "對話紀錄",
|
||||||
"chat_input_guide_lexicon_is_empty": "尚未設定詞彙庫",
|
"chat_input_guide_lexicon_is_empty": "尚未設定詞彙庫",
|
||||||
"chat_test_app": "調試-{{name}}",
|
"chat_test_app": "除錯-{{name}}",
|
||||||
"citations": "{{num}} 筆引用",
|
"citations": "{{num}} 筆引用",
|
||||||
"click_contextual_preview": "點選檢視上下文預覽",
|
"click_contextual_preview": "點選檢視上下文預覽",
|
||||||
"completion_finish_close": "連接斷開",
|
"completion_finish_close": "連接斷開",
|
||||||
"completion_finish_content_filter": "觸發安全風控",
|
"completion_finish_content_filter": "觸發安全風控",
|
||||||
"completion_finish_function_call": "函數調用",
|
"completion_finish_function_call": "函式呼叫",
|
||||||
"completion_finish_length": "超出回复限制",
|
"completion_finish_length": "超出回覆限制",
|
||||||
"completion_finish_null": "未知",
|
"completion_finish_null": "未知",
|
||||||
"completion_finish_reason": "完成原因",
|
"completion_finish_reason": "完成原因",
|
||||||
"completion_finish_stop": "正常完成",
|
"completion_finish_stop": "正常完成",
|
||||||
"completion_finish_tool_calls": "工具調用",
|
"completion_finish_tool_calls": "工具呼叫",
|
||||||
"config_input_guide": "設定輸入導引",
|
"config_input_guide": "設定輸入導引",
|
||||||
"config_input_guide_lexicon": "設定詞彙庫",
|
"config_input_guide_lexicon": "設定詞彙庫",
|
||||||
"config_input_guide_lexicon_title": "設定詞彙庫",
|
"config_input_guide_lexicon_title": "設定詞彙庫",
|
||||||
@@ -27,10 +27,10 @@
|
|||||||
"contextual_preview": "上下文預覽 {{num}} 筆",
|
"contextual_preview": "上下文預覽 {{num}} 筆",
|
||||||
"csv_input_lexicon_tip": "僅支援 CSV 批次匯入,點選下載範本",
|
"csv_input_lexicon_tip": "僅支援 CSV 批次匯入,點選下載範本",
|
||||||
"custom_input_guide_url": "自訂詞彙庫網址",
|
"custom_input_guide_url": "自訂詞彙庫網址",
|
||||||
"data_source": "來源知識庫: {{name}}",
|
"data_source": "來源知識庫:{{name}}",
|
||||||
"dataset_quote_type error": "知識庫引用類型錯誤,正確類型:{ datasetId: string }[]",
|
"dataset_quote_type error": "知識庫引用類型錯誤,正確類型:{ datasetId: string }[]",
|
||||||
"delete_all_input_guide_confirm": "確定要清除輸入導引詞彙庫嗎?",
|
"delete_all_input_guide_confirm": "確定要清除輸入導引詞彙庫嗎?",
|
||||||
"download_chunks": "下載數據",
|
"download_chunks": "下載資料",
|
||||||
"empty_directory": "此目錄中已無項目可選~",
|
"empty_directory": "此目錄中已無項目可選~",
|
||||||
"file_amount_over": "超出檔案數量上限 {{max}}",
|
"file_amount_over": "超出檔案數量上限 {{max}}",
|
||||||
"file_input": "檔案輸入",
|
"file_input": "檔案輸入",
|
||||||
@@ -52,12 +52,12 @@
|
|||||||
"not_select_file": "尚未選取檔案",
|
"not_select_file": "尚未選取檔案",
|
||||||
"plugins_output": "外掛程式輸出",
|
"plugins_output": "外掛程式輸出",
|
||||||
"press_to_speak": "按住說話",
|
"press_to_speak": "按住說話",
|
||||||
"query_extension_IO_tokens": "問題優化輸入/輸出 Tokens",
|
"query_extension_IO_tokens": "問題最佳化輸入/輸出 Tokens",
|
||||||
"question_tip": "由上至下,各個模組的回應順序",
|
"question_tip": "由上至下,各個模組的回應順序",
|
||||||
"read_raw_source": "打開原文",
|
"read_raw_source": "開啟原文",
|
||||||
"reasoning_text": "思考過程",
|
"reasoning_text": "思考過程",
|
||||||
"release_cancel": "鬆開取消",
|
"release_cancel": "鬆開取消",
|
||||||
"release_send": "鬆開發送,上滑取消",
|
"release_send": "鬆開傳送,上滑取消",
|
||||||
"response.child total points": "子工作流程點數消耗",
|
"response.child total points": "子工作流程點數消耗",
|
||||||
"response.dataset_concat_length": "合併總數",
|
"response.dataset_concat_length": "合併總數",
|
||||||
"response.node_inputs": "節點輸入",
|
"response.node_inputs": "節點輸入",
|
||||||
@@ -72,7 +72,7 @@
|
|||||||
"to_dataset": "前往知識庫",
|
"to_dataset": "前往知識庫",
|
||||||
"unsupported_file_type": "不支援的檔案類型",
|
"unsupported_file_type": "不支援的檔案類型",
|
||||||
"upload": "上傳",
|
"upload": "上傳",
|
||||||
"variable_invisable_in_share": "自定義變量在免登錄鏈接中不可見",
|
"variable_invisable_in_share": "自定義變數在免登入連結中不可見",
|
||||||
"view_citations": "檢視引用",
|
"view_citations": "檢視引用",
|
||||||
"web_site_sync": "網站同步"
|
"web_site_sync": "網站同步"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
{
|
{
|
||||||
"App": "應用程式",
|
"App": "應用程式",
|
||||||
"Click_to_expand": "點擊查看詳情",
|
"Click_to_expand": "點選檢視詳細資訊",
|
||||||
"Download": "下載",
|
"Download": "下載",
|
||||||
"Export": "匯出",
|
"Export": "匯出",
|
||||||
"FAQ.ai_point_a": "每次呼叫 AI 模型時,都會消耗一定數量的 AI 點數。詳細的計算標準請參考上方的「AI 點數計算標準」。\nToken 計算採用與 GPT3.5 相同的公式,1 Token ≈ 0.7 個中文字 ≈ 0.9 個英文單字,連續出現的字元可能會被視為 1 個 Token。",
|
"FAQ.ai_point_a": "每次呼叫 AI 模型時,都會消耗一定數量的 AI 點數。詳細的計算標準請參考上方的「AI 點數計算標準」。\nToken 計算採用與 GPT3.5 相同的公式,1 Token ≈ 0.7 個中文字 ≈ 0.9 個英文單字,連續出現的字元可能會被視為 1 個 Token。",
|
||||||
"FAQ.ai_point_expire_a": "會過期。目前方案過期後,AI 點數將會清空並更新為新方案的 AI 點數。年度方案的 AI 點數有效期為一年,而不是每個月重置。",
|
"FAQ.ai_point_expire_a": "會過期。目前方案過期後,AI 點數將會清空並更新為新方案的 AI 點數。年度方案的 AI 點數有效期為一年,而不是每個月重設。",
|
||||||
"FAQ.ai_point_expire_q": "AI 點數會過期嗎?",
|
"FAQ.ai_point_expire_q": "AI 點數會過期嗎?",
|
||||||
"FAQ.ai_point_q": "什麼是 AI 點數?",
|
"FAQ.ai_point_q": "什麼是 AI 點數?",
|
||||||
"FAQ.check_subscription_a": "帳號 - 個人資訊 - 方案詳細資訊 - 使用狀況。您可以檢視已訂閱方案的生效和到期時間。當付費方案到期後,將自動切換為免費版。",
|
"FAQ.check_subscription_a": "帳號 - 個人資訊 - 方案詳細資訊 - 使用狀況。您可以檢視已訂閱方案的生效和到期時間。當付費方案到期後,將自動切換為免費版。",
|
||||||
@@ -46,7 +46,7 @@
|
|||||||
"click_to_resume": "點選繼續",
|
"click_to_resume": "點選繼續",
|
||||||
"code_editor": "程式碼編輯器",
|
"code_editor": "程式碼編輯器",
|
||||||
"code_error.account_error": "帳號名稱或密碼錯誤",
|
"code_error.account_error": "帳號名稱或密碼錯誤",
|
||||||
"code_error.account_not_found": "用戶未註冊",
|
"code_error.account_not_found": "使用者未註冊",
|
||||||
"code_error.app_error.invalid_app_type": "無效的應用程式類型",
|
"code_error.app_error.invalid_app_type": "無效的應用程式類型",
|
||||||
"code_error.app_error.invalid_owner": "非法的應用程式擁有者",
|
"code_error.app_error.invalid_owner": "非法的應用程式擁有者",
|
||||||
"code_error.app_error.not_exist": "應用程式不存在",
|
"code_error.app_error.not_exist": "應用程式不存在",
|
||||||
@@ -90,7 +90,7 @@
|
|||||||
"code_error.team_error.group_name_duplicate": "群組名稱重複",
|
"code_error.team_error.group_name_duplicate": "群組名稱重複",
|
||||||
"code_error.team_error.group_name_empty": "群組名稱不能為空",
|
"code_error.team_error.group_name_empty": "群組名稱不能為空",
|
||||||
"code_error.team_error.group_not_exist": "群組不存在",
|
"code_error.team_error.group_not_exist": "群組不存在",
|
||||||
"code_error.team_error.invitation_link_invalid": "邀請鏈接已失效",
|
"code_error.team_error.invitation_link_invalid": "邀請連結已失效",
|
||||||
"code_error.team_error.not_user": "找不到該成員",
|
"code_error.team_error.not_user": "找不到該成員",
|
||||||
"code_error.team_error.org_member_duplicated": "重複的組織成員",
|
"code_error.team_error.org_member_duplicated": "重複的組織成員",
|
||||||
"code_error.team_error.org_member_not_exist": "組織成員不存在",
|
"code_error.team_error.org_member_not_exist": "組織成員不存在",
|
||||||
@@ -102,7 +102,7 @@
|
|||||||
"code_error.team_error.too_many_invitations": "您的有效邀請連結數已達上限,請先清理連結",
|
"code_error.team_error.too_many_invitations": "您的有效邀請連結數已達上限,請先清理連結",
|
||||||
"code_error.team_error.un_auth": "無權操作此團隊",
|
"code_error.team_error.un_auth": "無權操作此團隊",
|
||||||
"code_error.team_error.user_not_active": "使用者未接受或已離開團隊",
|
"code_error.team_error.user_not_active": "使用者未接受或已離開團隊",
|
||||||
"code_error.team_error.website_sync_not_enough": "免費版無法使用Web站點同步~",
|
"code_error.team_error.website_sync_not_enough": "免費版無法使用 Web 站點同步~",
|
||||||
"code_error.team_error.you_have_been_in_the_team": "你已經在該團隊中",
|
"code_error.team_error.you_have_been_in_the_team": "你已經在該團隊中",
|
||||||
"code_error.token_error_code.403": "登入狀態無效,請重新登入",
|
"code_error.token_error_code.403": "登入狀態無效,請重新登入",
|
||||||
"code_error.user_error.balance_not_enough": "帳戶餘額不足",
|
"code_error.user_error.balance_not_enough": "帳戶餘額不足",
|
||||||
@@ -118,7 +118,7 @@
|
|||||||
"common.Cancel": "取消",
|
"common.Cancel": "取消",
|
||||||
"common.Choose": "選擇",
|
"common.Choose": "選擇",
|
||||||
"common.Close": "關閉",
|
"common.Close": "關閉",
|
||||||
"common.Code": "源碼",
|
"common.Code": "原始碼",
|
||||||
"common.Config": "設定",
|
"common.Config": "設定",
|
||||||
"common.Confirm": "確認",
|
"common.Confirm": "確認",
|
||||||
"common.Confirm Create": "確認建立",
|
"common.Confirm Create": "確認建立",
|
||||||
@@ -291,7 +291,7 @@
|
|||||||
"core.app.Chat Variable": "對話變數",
|
"core.app.Chat Variable": "對話變數",
|
||||||
"core.app.Config schedule plan": "設定排程執行",
|
"core.app.Config schedule plan": "設定排程執行",
|
||||||
"core.app.Config whisper": "設定語音輸入",
|
"core.app.Config whisper": "設定語音輸入",
|
||||||
"core.app.Config_auto_execute": "點選配置自動執行規則",
|
"core.app.Config_auto_execute": "點選設定自動執行規則",
|
||||||
"core.app.Interval timer config": "排程執行設定",
|
"core.app.Interval timer config": "排程執行設定",
|
||||||
"core.app.Interval timer run": "排程執行",
|
"core.app.Interval timer run": "排程執行",
|
||||||
"core.app.Interval timer tip": "可排程執行應用程式",
|
"core.app.Interval timer tip": "可排程執行應用程式",
|
||||||
@@ -304,7 +304,7 @@
|
|||||||
"core.app.QG.Custom prompt tip1": "為確保生成的內容遵循正確格式,",
|
"core.app.QG.Custom prompt tip1": "為確保生成的內容遵循正確格式,",
|
||||||
"core.app.QG.Custom prompt tip2": "【黃色部分提示詞】",
|
"core.app.QG.Custom prompt tip2": "【黃色部分提示詞】",
|
||||||
"core.app.QG.Custom prompt tip3": "不允許修改",
|
"core.app.QG.Custom prompt tip3": "不允許修改",
|
||||||
"core.app.QG.Fixed Prompt": "請嚴格遵循格式規則:以 JSON 格式返回題目:\n['問題1','問題2','問題3']。",
|
"core.app.QG.Fixed Prompt": "請嚴格遵循格式規則:以 JSON 格式返回題目:\n['問題 1','問題 2','問題 3']。",
|
||||||
"core.app.Question Guide": "猜你想問",
|
"core.app.Question Guide": "猜你想問",
|
||||||
"core.app.Quote prompt": "引用範本提示詞",
|
"core.app.Quote prompt": "引用範本提示詞",
|
||||||
"core.app.Quote templates": "引用內容範本",
|
"core.app.Quote templates": "引用內容範本",
|
||||||
@@ -373,7 +373,7 @@
|
|||||||
"core.app.tip.Add a intro to app": "快來為應用程式寫一個介紹",
|
"core.app.tip.Add a intro to app": "快來為應用程式寫一個介紹",
|
||||||
"core.app.tip.chatNodeSystemPromptTip": "在此輸入提示詞",
|
"core.app.tip.chatNodeSystemPromptTip": "在此輸入提示詞",
|
||||||
"core.app.tip.systemPromptTip": "模型固定的引導詞,透過調整此內容,可以引導模型對話方向。此內容會固定在上下文的開頭。可透過輸入 / 插入變數。\n如果關聯了知識庫,您還可以透過適當的描述,引導模型何時去呼叫知識庫搜尋。例如:\n您是電影《星際效應》的助手,當使用者詢問與《星際效應》相關的內容時,請搜尋知識庫並根據搜尋結果回答。",
|
"core.app.tip.systemPromptTip": "模型固定的引導詞,透過調整此內容,可以引導模型對話方向。此內容會固定在上下文的開頭。可透過輸入 / 插入變數。\n如果關聯了知識庫,您還可以透過適當的描述,引導模型何時去呼叫知識庫搜尋。例如:\n您是電影《星際效應》的助手,當使用者詢問與《星際效應》相關的內容時,請搜尋知識庫並根據搜尋結果回答。",
|
||||||
"core.app.tip.variableTip": "可以在對話開始前,要求用戶填寫一些內容作為本輪對話的特定變量。\n該模塊位於開場引導之後。\n\n輸入框中,可通過 / 激活變量選擇,例如:提示詞、限定詞等",
|
"core.app.tip.variableTip": "可以在對話開始前,要求使用者填寫一些內容作為本輪對話的特定變數。\n該模組位於開場引導之後。\n\n輸入框中,可透過 / 啟用變數選擇,例如:提示詞、限定詞等",
|
||||||
"core.app.tip.welcomeTextTip": "每次對話開始前,傳送一段初始內容。支援標準 Markdown 語法。可使用的額外標記:\n[快速按鍵]:使用者點選後可以直接傳送該問題",
|
"core.app.tip.welcomeTextTip": "每次對話開始前,傳送一段初始內容。支援標準 Markdown 語法。可使用的額外標記:\n[快速按鍵]:使用者點選後可以直接傳送該問題",
|
||||||
"core.app.tool_label.doc": "使用文件",
|
"core.app.tool_label.doc": "使用文件",
|
||||||
"core.app.tool_label.github": "GitHub 網址",
|
"core.app.tool_label.github": "GitHub 網址",
|
||||||
@@ -452,7 +452,7 @@
|
|||||||
"core.chat.markdown.Edit Question": "編輯問題",
|
"core.chat.markdown.Edit Question": "編輯問題",
|
||||||
"core.chat.markdown.Quick Question": "點我立即發問",
|
"core.chat.markdown.Quick Question": "點我立即發問",
|
||||||
"core.chat.markdown.Send Question": "傳送問題",
|
"core.chat.markdown.Send Question": "傳送問題",
|
||||||
"core.chat.module_unexist": "運行失敗:應用缺失組件",
|
"core.chat.module_unexist": "執行失敗:應用遺失元件",
|
||||||
"core.chat.quote.Quote Tip": "此處僅顯示實際引用內容,若資料有更新,此處不會即時更新",
|
"core.chat.quote.Quote Tip": "此處僅顯示實際引用內容,若資料有更新,此處不會即時更新",
|
||||||
"core.chat.quote.Read Quote": "檢視引用",
|
"core.chat.quote.Read Quote": "檢視引用",
|
||||||
"core.chat.quote.afterUpdate": "更新後",
|
"core.chat.quote.afterUpdate": "更新後",
|
||||||
@@ -625,10 +625,10 @@
|
|||||||
"core.dataset.search.score.reRank desc": "透過重新排名模型計算句子之間的關聯度,範圍為 0 到 1。",
|
"core.dataset.search.score.reRank desc": "透過重新排名模型計算句子之間的關聯度,範圍為 0 到 1。",
|
||||||
"core.dataset.search.score.rrf": "綜合排名",
|
"core.dataset.search.score.rrf": "綜合排名",
|
||||||
"core.dataset.search.score.rrf desc": "使用倒數排名融合方法,合併多個搜尋結果。",
|
"core.dataset.search.score.rrf desc": "使用倒數排名融合方法,合併多個搜尋結果。",
|
||||||
"core.dataset.search.search mode": "搜索方式",
|
"core.dataset.search.search mode": "搜尋方式",
|
||||||
"core.dataset.status.active": "已就緒",
|
"core.dataset.status.active": "已就緒",
|
||||||
"core.dataset.status.syncing": "同步中",
|
"core.dataset.status.syncing": "同步中",
|
||||||
"core.dataset.status.waiting": "排队中",
|
"core.dataset.status.waiting": "排隊中",
|
||||||
"core.dataset.test.Batch test": "批次測試",
|
"core.dataset.test.Batch test": "批次測試",
|
||||||
"core.dataset.test.Batch test Placeholder": "選擇一個 CSV 檔案",
|
"core.dataset.test.Batch test Placeholder": "選擇一個 CSV 檔案",
|
||||||
"core.dataset.test.Search Test": "搜尋測試",
|
"core.dataset.test.Search Test": "搜尋測試",
|
||||||
@@ -644,7 +644,7 @@
|
|||||||
"core.dataset.training.Agent queue": "問答訓練排隊中",
|
"core.dataset.training.Agent queue": "問答訓練排隊中",
|
||||||
"core.dataset.training.Auto mode": "補充索引",
|
"core.dataset.training.Auto mode": "補充索引",
|
||||||
"core.dataset.training.Auto mode Tip": "透過子索引以及呼叫模型產生相關問題與摘要,來增加資料區塊的語意豐富度,更有利於檢索。需要消耗更多的儲存空間並增加 AI 呼叫次數。",
|
"core.dataset.training.Auto mode Tip": "透過子索引以及呼叫模型產生相關問題與摘要,來增加資料區塊的語意豐富度,更有利於檢索。需要消耗更多的儲存空間並增加 AI 呼叫次數。",
|
||||||
"core.dataset.training.Chunk mode": "直接分块",
|
"core.dataset.training.Chunk mode": "直接分塊",
|
||||||
"core.dataset.training.Full": "預計 20 分鐘以上",
|
"core.dataset.training.Full": "預計 20 分鐘以上",
|
||||||
"core.dataset.training.Leisure": "閒置",
|
"core.dataset.training.Leisure": "閒置",
|
||||||
"core.dataset.training.QA mode": "問答對提取",
|
"core.dataset.training.QA mode": "問答對提取",
|
||||||
@@ -689,7 +689,7 @@
|
|||||||
"core.module.Variable": "全域變數",
|
"core.module.Variable": "全域變數",
|
||||||
"core.module.Variable Setting": "變數設定",
|
"core.module.Variable Setting": "變數設定",
|
||||||
"core.module.edit.Field Name Cannot Be Empty": "欄位名稱不能為空",
|
"core.module.edit.Field Name Cannot Be Empty": "欄位名稱不能為空",
|
||||||
"core.module.edit.Field Value Type Cannot Be Empty": "可選數據類型不能為空",
|
"core.module.edit.Field Value Type Cannot Be Empty": "可選資料類型不能為空",
|
||||||
"core.module.extract.Add field": "新增欄位",
|
"core.module.extract.Add field": "新增欄位",
|
||||||
"core.module.extract.Enum Description": "列舉此欄位可能的值,每行一個",
|
"core.module.extract.Enum Description": "列舉此欄位可能的值,每行一個",
|
||||||
"core.module.extract.Enum Value": "列舉值",
|
"core.module.extract.Enum Value": "列舉值",
|
||||||
@@ -743,7 +743,7 @@
|
|||||||
"core.module.template.AI support tool tip": "支援函式呼叫的模型可以更好地使用工具呼叫。",
|
"core.module.template.AI support tool tip": "支援函式呼叫的模型可以更好地使用工具呼叫。",
|
||||||
"core.module.template.Basic Node": "基本功能",
|
"core.module.template.Basic Node": "基本功能",
|
||||||
"core.module.template.Query extension": "問題最佳化",
|
"core.module.template.Query extension": "問題最佳化",
|
||||||
"core.module.template.System Plugin": "系統插件",
|
"core.module.template.System Plugin": "系統外掛",
|
||||||
"core.module.template.System input module": "系統輸入模組",
|
"core.module.template.System input module": "系統輸入模組",
|
||||||
"core.module.template.Team app": "團隊應用程式",
|
"core.module.template.Team app": "團隊應用程式",
|
||||||
"core.module.template.Tool module": "工具",
|
"core.module.template.Tool module": "工具",
|
||||||
@@ -781,7 +781,7 @@
|
|||||||
"core.view_chat_detail": "檢視對話詳細資料",
|
"core.view_chat_detail": "檢視對話詳細資料",
|
||||||
"core.workflow.Can not delete node": "此節點不允許刪除",
|
"core.workflow.Can not delete node": "此節點不允許刪除",
|
||||||
"core.workflow.Change input type tip": "修改輸入類型將清空已填寫的值,請確認!",
|
"core.workflow.Change input type tip": "修改輸入類型將清空已填寫的值,請確認!",
|
||||||
"core.workflow.Check Failed": "工作流校驗失敗,請檢查是否缺失、缺值,連線是否正常",
|
"core.workflow.Check Failed": "工作流校驗失敗,請檢查是否遺失、缺值,連線是否正常",
|
||||||
"core.workflow.Confirm stop debug": "確認停止除錯?除錯資訊將不會保留。",
|
"core.workflow.Confirm stop debug": "確認停止除錯?除錯資訊將不會保留。",
|
||||||
"core.workflow.Copy node": "已複製節點",
|
"core.workflow.Copy node": "已複製節點",
|
||||||
"core.workflow.Custom inputs": "自訂輸入",
|
"core.workflow.Custom inputs": "自訂輸入",
|
||||||
@@ -826,14 +826,14 @@
|
|||||||
"core.workflow.template.Interactive": "互動",
|
"core.workflow.template.Interactive": "互動",
|
||||||
"core.workflow.template.Multimodal": "多模態",
|
"core.workflow.template.Multimodal": "多模態",
|
||||||
"core.workflow.template.Search": "搜尋",
|
"core.workflow.template.Search": "搜尋",
|
||||||
"core.workflow.tool.Handle": "工具連接器",
|
"core.workflow.tool.Handle": "工具聯結器",
|
||||||
"core.workflow.tool.Select Tool": "選擇工具",
|
"core.workflow.tool.Select Tool": "選擇工具",
|
||||||
"core.workflow.value": "值",
|
"core.workflow.value": "值",
|
||||||
"core.workflow.variable": "變數",
|
"core.workflow.variable": "變數",
|
||||||
"create": "建立",
|
"create": "建立",
|
||||||
"cron_job_run_app": "排程任務",
|
"cron_job_run_app": "排程任務",
|
||||||
"data_index_custom": "自定義索引",
|
"data_index_custom": "自定義索引",
|
||||||
"data_index_default": "默認索引",
|
"data_index_default": "預設索引",
|
||||||
"data_index_image": "圖片索引",
|
"data_index_image": "圖片索引",
|
||||||
"data_index_question": "推測問題索引",
|
"data_index_question": "推測問題索引",
|
||||||
"data_index_summary": "摘要索引",
|
"data_index_summary": "摘要索引",
|
||||||
@@ -879,25 +879,25 @@
|
|||||||
"dataset_data_input_chunk_content": "內容",
|
"dataset_data_input_chunk_content": "內容",
|
||||||
"dataset_data_input_q": "問題",
|
"dataset_data_input_q": "問題",
|
||||||
"dataset_data_input_qa": "QA 模式",
|
"dataset_data_input_qa": "QA 模式",
|
||||||
"dataset_text_model_tip": "用於知識庫預處理階段的文本處理,例如自動補充索引、問答對提取。",
|
"dataset_text_model_tip": "用於知識庫預處理階段的文字處理,例如自動補充索引、問答對提取。",
|
||||||
"deep_rag_search": "深度搜索",
|
"deep_rag_search": "深度搜尋",
|
||||||
"delete_api": "確認刪除此 API 金鑰?\n刪除後該金鑰將立即失效,對應的對話記錄不會被刪除,請確認!",
|
"delete_api": "確認刪除此 API 金鑰?\n刪除後該金鑰將立即失效,對應的對話記錄不會被刪除,請確認!",
|
||||||
"embedding_model_not_config": "檢測到沒有可用的索引模型",
|
"embedding_model_not_config": "偵測到沒有可用的索引模型",
|
||||||
"error.Create failed": "建立失敗",
|
"error.Create failed": "建立失敗",
|
||||||
"error.code_error": "驗證碼錯誤",
|
"error.code_error": "驗證碼錯誤",
|
||||||
"error.fileNotFound": "找不到檔案",
|
"error.fileNotFound": "找不到檔案",
|
||||||
"error.inheritPermissionError": "繼承權限錯誤",
|
"error.inheritPermissionError": "繼承權限錯誤",
|
||||||
"error.invalid_params": "參數無效",
|
"error.invalid_params": "參數無效",
|
||||||
"error.missingParams": "參數不足",
|
"error.missingParams": "參數不足",
|
||||||
"error.send_auth_code_too_frequently": "請勿頻繁獲取驗證碼",
|
"error.send_auth_code_too_frequently": "請勿頻繁取得驗證碼",
|
||||||
"error.too_many_request": "請求太頻繁了,請稍後重試",
|
"error.too_many_request": "請求太頻繁了,請稍後重試",
|
||||||
"error.upload_file_error_filename": "{{name}} 上傳失敗",
|
"error.upload_file_error_filename": "{{name}} 上傳失敗",
|
||||||
"error.upload_image_error": "上傳文件失敗",
|
"error.upload_image_error": "上傳文件失敗",
|
||||||
"error.username_empty": "帳號不能為空",
|
"error.username_empty": "帳號不能為空",
|
||||||
"error_collection_not_exist": "集合不存在",
|
"error_collection_not_exist": "集合不存在",
|
||||||
"error_embedding_not_config": "未配置索引模型",
|
"error_embedding_not_config": "未設定索引模型",
|
||||||
"error_llm_not_config": "未配置文件理解模型",
|
"error_llm_not_config": "未設定文件理解模型",
|
||||||
"error_vlm_not_config": "未配置圖片理解模型",
|
"error_vlm_not_config": "未設定圖片理解模型",
|
||||||
"extraction_results": "提取結果",
|
"extraction_results": "提取結果",
|
||||||
"field_name": "欄位名稱",
|
"field_name": "欄位名稱",
|
||||||
"free": "免費",
|
"free": "免費",
|
||||||
@@ -913,7 +913,7 @@
|
|||||||
"info.include": "包含標準方案與額外資源包",
|
"info.include": "包含標準方案與額外資源包",
|
||||||
"info.node_info": "調整此模組會影響工具呼叫的時機。\n您可以透過精確描述此模組功能,引導模型進行工具呼叫。",
|
"info.node_info": "調整此模組會影響工具呼叫的時機。\n您可以透過精確描述此模組功能,引導模型進行工具呼叫。",
|
||||||
"info.old_version_attention": "偵測到您的進階編排為舊版本,系統將自動格式化為新版工作流程。\n\n由於版本差異較大,可能導致某些工作流程無法正常排列。請重新手動連接工作流程。如果仍然異常,請嘗試刪除對應節點後重新新增。\n\n您可以直接點選除錯來測試工作流程。除錯完成後,點選發布。直到您點選發布,新工作流程才會真正儲存生效。\n\n在您發布新工作流程之前,自動儲存將不會生效。",
|
"info.old_version_attention": "偵測到您的進階編排為舊版本,系統將自動格式化為新版工作流程。\n\n由於版本差異較大,可能導致某些工作流程無法正常排列。請重新手動連接工作流程。如果仍然異常,請嘗試刪除對應節點後重新新增。\n\n您可以直接點選除錯來測試工作流程。除錯完成後,點選發布。直到您點選發布,新工作流程才會真正儲存生效。\n\n在您發布新工作流程之前,自動儲存將不會生效。",
|
||||||
"info.open_api_notice": "您可以填寫 OpenAI/OneAPI 的相關金鑰。如果您填寫了此內容,在線上平台使用【AI 對話】、【問題分類】和【內容提取】將使用您填寫的金鑰,不會計費。請確認您的金鑰是否有存取對應模型的權限。GPT 模型可以選擇 FastAI。",
|
"info.open_api_notice": "您可以填寫 OpenAI/OneAPI 的相關金鑰。如果您填寫了此內容,在線上平臺使用【AI 對話】、【問題分類】和【內容提取】將使用您填寫的金鑰,不會計費。請確認您的金鑰是否有存取對應模型的權限。GPT 模型可以選擇 FastAI。",
|
||||||
"info.open_api_placeholder": "請求網址,預設為 OpenAI 官方。可填寫中轉網址,未自動補全 \"v1\"",
|
"info.open_api_placeholder": "請求網址,預設為 OpenAI 官方。可填寫中轉網址,未自動補全 \"v1\"",
|
||||||
"info.resource": "資源使用量",
|
"info.resource": "資源使用量",
|
||||||
"invalid_variable": "無效變數",
|
"invalid_variable": "無效變數",
|
||||||
@@ -923,7 +923,7 @@
|
|||||||
"item_name": "欄位名稱",
|
"item_name": "欄位名稱",
|
||||||
"just_now": "剛剛",
|
"just_now": "剛剛",
|
||||||
"key_repetition": "鍵值重複",
|
"key_repetition": "鍵值重複",
|
||||||
"llm_model_not_config": "檢測到沒有可用的語言模型",
|
"llm_model_not_config": "偵測到沒有可用的語言模型",
|
||||||
"max_quote_tokens": "引用上限",
|
"max_quote_tokens": "引用上限",
|
||||||
"max_quote_tokens_tips": "單次搜尋最大的 token 數量,中文約 1 字=1.7 tokens,英文約 1 字=1 token",
|
"max_quote_tokens_tips": "單次搜尋最大的 token 數量,中文約 1 字=1.7 tokens,英文約 1 字=1 token",
|
||||||
"min_similarity": "最低相關度",
|
"min_similarity": "最低相關度",
|
||||||
@@ -964,14 +964,14 @@
|
|||||||
"new_create": "建立新項目",
|
"new_create": "建立新項目",
|
||||||
"no": "否",
|
"no": "否",
|
||||||
"no_laf_env": "系統未設定 LAF 環境",
|
"no_laf_env": "系統未設定 LAF 環境",
|
||||||
"not_model_config": "未配置相關模型",
|
"not_model_config": "未設定相關模型",
|
||||||
"not_yet_introduced": "暫無介紹",
|
"not_yet_introduced": "暫無介紹",
|
||||||
"option": "選項",
|
"option": "選項",
|
||||||
"pay.amount": "金額",
|
"pay.amount": "金額",
|
||||||
"pay.package_tip.buy": "您購買的方案等級低於目前方案,該方案將在目前方案過期後生效。\n您可在帳戶 - 個人資訊 - 方案詳細資訊中檢視方案使用情況。",
|
"pay.package_tip.buy": "您購買的方案等級低於目前方案,該方案將在目前方案過期後生效。\n您可在帳戶 - 個人資訊 - 方案詳細資訊中檢視方案使用情況。",
|
||||||
"pay.package_tip.renewal": "您正在續約方案。您可在帳戶 - 個人資訊 - 方案詳細資訊中檢視方案使用情況。",
|
"pay.package_tip.renewal": "您正在續約方案。您可在帳戶 - 個人資訊 - 方案詳細資訊中檢視方案使用情況。",
|
||||||
"pay.package_tip.upgrade": "您購買的方案等級高於目前方案,該方案將立即生效,目前方案將延後生效。您可在帳戶 - 個人資訊 - 方案詳細資訊中檢視方案使用情況。",
|
"pay.package_tip.upgrade": "您購買的方案等級高於目前方案,該方案將立即生效,目前方案將延後生效。您可在帳戶 - 個人資訊 - 方案詳細資訊中檢視方案使用情況。",
|
||||||
"pay.wechat": "請微信掃碼付款: {{price}}元\n\n付款完成前,請勿關閉頁面",
|
"pay.wechat": "請微信掃碼付款:{{price}}元\n\n付款完成前,請勿關閉頁面",
|
||||||
"pay.yuan": "{{amount}} 元",
|
"pay.yuan": "{{amount}} 元",
|
||||||
"permission.Collaborator": "協作者",
|
"permission.Collaborator": "協作者",
|
||||||
"permission.Default permission": "預設權限",
|
"permission.Default permission": "預設權限",
|
||||||
@@ -1022,7 +1022,7 @@
|
|||||||
"plugin.path": "路徑",
|
"plugin.path": "路徑",
|
||||||
"prompt_input_placeholder": "請輸入提示詞",
|
"prompt_input_placeholder": "請輸入提示詞",
|
||||||
"question_feedback": "工單諮詢",
|
"question_feedback": "工單諮詢",
|
||||||
"read_quote": "查看引用",
|
"read_quote": "檢視引用",
|
||||||
"required": "必填",
|
"required": "必填",
|
||||||
"rerank_weight": "重排權重",
|
"rerank_weight": "重排權重",
|
||||||
"resume_failed": "恢復失敗",
|
"resume_failed": "恢復失敗",
|
||||||
@@ -1040,7 +1040,7 @@
|
|||||||
"support.outlink.Max usage points tip": "此連結最多允許使用多少點數,超出後將無法使用。-1 代表無限制。",
|
"support.outlink.Max usage points tip": "此連結最多允許使用多少點數,超出後將無法使用。-1 代表無限制。",
|
||||||
"support.outlink.Usage points": "點數消耗",
|
"support.outlink.Usage points": "點數消耗",
|
||||||
"support.outlink.share.Chat_quote_reader": "全文閱讀器",
|
"support.outlink.share.Chat_quote_reader": "全文閱讀器",
|
||||||
"support.outlink.share.Full_text tips": "允許閱讀該引用片段來源的完整數據集",
|
"support.outlink.share.Full_text tips": "允許閱讀該引用片段來源的完整資料集",
|
||||||
"support.outlink.share.Response Quote": "回傳引用",
|
"support.outlink.share.Response Quote": "回傳引用",
|
||||||
"support.outlink.share.Response Quote tips": "在分享連結中回傳引用內容,但不允許使用者下載原始文件",
|
"support.outlink.share.Response Quote tips": "在分享連結中回傳引用內容,但不允許使用者下載原始文件",
|
||||||
"support.outlink.share.running_node": "執行節點",
|
"support.outlink.share.running_node": "執行節點",
|
||||||
@@ -1090,8 +1090,8 @@
|
|||||||
"support.user.team.Team Tags Async Success": "同步完成",
|
"support.user.team.Team Tags Async Success": "同步完成",
|
||||||
"support.user.team.member": "成員",
|
"support.user.team.member": "成員",
|
||||||
"support.wallet.Ai point every thousand tokens": "{{points}} 點數/1K tokens",
|
"support.wallet.Ai point every thousand tokens": "{{points}} 點數/1K tokens",
|
||||||
"support.wallet.Ai point every thousand tokens_input": "輸入:{{points}} 积分/1K tokens",
|
"support.wallet.Ai point every thousand tokens_input": "輸入:{{points}} 積分/1K tokens",
|
||||||
"support.wallet.Ai point every thousand tokens_output": "輸出:{{points}} 积分/1K tokens",
|
"support.wallet.Ai point every thousand tokens_output": "輸出:{{points}} 積分/1K tokens",
|
||||||
"support.wallet.Amount": "金額",
|
"support.wallet.Amount": "金額",
|
||||||
"support.wallet.App_amount_not_sufficient": "您的應用數量已達上限,請升級套餐後繼續使用。",
|
"support.wallet.App_amount_not_sufficient": "您的應用數量已達上限,請升級套餐後繼續使用。",
|
||||||
"support.wallet.Buy": "購買",
|
"support.wallet.Buy": "購買",
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
"api_file": "API 檔案庫",
|
"api_file": "API 檔案庫",
|
||||||
"api_url": "介面位址",
|
"api_url": "介面位址",
|
||||||
"auto_indexes": "自動生成補充索引",
|
"auto_indexes": "自動生成補充索引",
|
||||||
"auto_indexes_tips": "通過大模型進行額外索引生成,提高語義豐富度,提高檢索的精度。",
|
"auto_indexes_tips": "透過大模型進行額外索引生成,提高語義豐富度,提高檢索的精度。",
|
||||||
"auto_training_queue": "增強索引排隊",
|
"auto_training_queue": "增強索引排隊",
|
||||||
"chunk_max_tokens": "分塊上限",
|
"chunk_max_tokens": "分塊上限",
|
||||||
"chunk_size": "分塊大小",
|
"chunk_size": "分塊大小",
|
||||||
@@ -12,8 +12,8 @@
|
|||||||
"collection.Create update time": "建立/更新時間",
|
"collection.Create update time": "建立/更新時間",
|
||||||
"collection.Training type": "分段模式",
|
"collection.Training type": "分段模式",
|
||||||
"collection.training_type": "處理模式",
|
"collection.training_type": "處理模式",
|
||||||
"collection_data_count": "數據量",
|
"collection_data_count": "資料量",
|
||||||
"collection_metadata_custom_pdf_parse": "PDF增強解析",
|
"collection_metadata_custom_pdf_parse": "PDF 增強解析",
|
||||||
"collection_metadata_image_parse": "圖片標註",
|
"collection_metadata_image_parse": "圖片標註",
|
||||||
"collection_not_support_retraining": "此集合類型不支援重新調整參數",
|
"collection_not_support_retraining": "此集合類型不支援重新調整參數",
|
||||||
"collection_not_support_sync": "該集合不支援同步",
|
"collection_not_support_sync": "該集合不支援同步",
|
||||||
@@ -22,13 +22,13 @@
|
|||||||
"collection_tags": "集合標籤",
|
"collection_tags": "集合標籤",
|
||||||
"common_dataset": "通用資料集",
|
"common_dataset": "通用資料集",
|
||||||
"common_dataset_desc": "可透過匯入檔案、網頁連結或手動輸入的方式建立資料集",
|
"common_dataset_desc": "可透過匯入檔案、網頁連結或手動輸入的方式建立資料集",
|
||||||
"config_sync_schedule": "配置定時同步",
|
"config_sync_schedule": "設定定時同步",
|
||||||
"confirm_to_rebuild_embedding_tip": "確定要為資料集切換索引嗎?\n切換索引是一個重要的操作,需要對您資料集內所有資料重新建立索引,可能需要較長時間,請確保帳號內剩餘點數充足。\n\n此外,您還需要注意修改使用此資料集的應用程式,避免與其他索引模型資料集混用。",
|
"confirm_to_rebuild_embedding_tip": "確定要為資料集切換索引嗎?\n切換索引是一個重要的操作,需要對您資料集內所有資料重新建立索引,可能需要較長時間,請確保帳號內剩餘點數充足。\n\n此外,您還需要注意修改使用此資料集的應用程式,避免與其他索引模型資料集混用。",
|
||||||
"core.dataset.import.Adjust parameters": "調整參數",
|
"core.dataset.import.Adjust parameters": "調整參數",
|
||||||
"custom_data_process_params": "自訂",
|
"custom_data_process_params": "自訂",
|
||||||
"custom_data_process_params_desc": "自訂資料處理規則",
|
"custom_data_process_params_desc": "自訂資料處理規則",
|
||||||
"custom_split_sign_tip": "允許你根據自定義的分隔符進行分塊。\n通常用於已處理好的數據,使用特定的分隔符來精確分塊。\n可以使用 | 符號表示多個分割符,例如:“。|.” 表示中英文句號。\n\n盡量避免使用正則相關特殊符號,例如: * () [] {} 等。",
|
"custom_split_sign_tip": "允許你根據自定義的分隔符進行分塊。\n通常用於已處理好的資料,使用特定的分隔符來精確分塊。\n可以使用 | 符號表示多個分割符,例如:“。|.”表示中英文句號。\n\n盡量避免使用正則相關特殊符號,例如:* () [] {} 等。",
|
||||||
"data_amount": "{{dataAmount}} 組數據, {{indexAmount}} 組索引",
|
"data_amount": "{{dataAmount}} 組資料,{{indexAmount}} 組索引",
|
||||||
"data_error_amount": "{{errorAmount}} 組訓練異常",
|
"data_error_amount": "{{errorAmount}} 組訓練異常",
|
||||||
"data_index_num": "索引 {{index}}",
|
"data_index_num": "索引 {{index}}",
|
||||||
"data_process_params": "處理參數",
|
"data_process_params": "處理參數",
|
||||||
@@ -37,8 +37,8 @@
|
|||||||
"dataset.Completed": "完成",
|
"dataset.Completed": "完成",
|
||||||
"dataset.Delete_Chunk": "刪除",
|
"dataset.Delete_Chunk": "刪除",
|
||||||
"dataset.Edit_Chunk": "編輯",
|
"dataset.Edit_Chunk": "編輯",
|
||||||
"dataset.Error_Message": "報錯信息",
|
"dataset.Error_Message": "報錯資訊",
|
||||||
"dataset.No_Error": "暫無異常信息",
|
"dataset.No_Error": "暫無異常資訊",
|
||||||
"dataset.Operation": "操作",
|
"dataset.Operation": "操作",
|
||||||
"dataset.ReTrain": "重試",
|
"dataset.ReTrain": "重試",
|
||||||
"dataset.Training Process": "訓練狀態",
|
"dataset.Training Process": "訓練狀態",
|
||||||
@@ -46,13 +46,13 @@
|
|||||||
"dataset.Training_Errors": "異常",
|
"dataset.Training_Errors": "異常",
|
||||||
"dataset.Training_QA": "{{count}} 組問答對訓練中",
|
"dataset.Training_QA": "{{count}} 組問答對訓練中",
|
||||||
"dataset.Training_Status": "訓練狀態",
|
"dataset.Training_Status": "訓練狀態",
|
||||||
"dataset.Training_Waiting": "需等待 {{count}} 組數據",
|
"dataset.Training_Waiting": "需等待 {{count}} 組資料",
|
||||||
"dataset.Unsupported operation": "操作不支持",
|
"dataset.Unsupported operation": "操作不支援",
|
||||||
"dataset.no_collections": "尚無資料集",
|
"dataset.no_collections": "尚無資料集",
|
||||||
"dataset.no_tags": "尚無標籤",
|
"dataset.no_tags": "尚無標籤",
|
||||||
"default_params": "預設",
|
"default_params": "預設",
|
||||||
"default_params_desc": "使用系統默認的參數和規則",
|
"default_params_desc": "使用系統預設的參數和規則",
|
||||||
"edit_dataset_config": "編輯知識庫配置",
|
"edit_dataset_config": "編輯知識庫設定",
|
||||||
"enhanced_indexes": "索引增強",
|
"enhanced_indexes": "索引增強",
|
||||||
"error.collectionNotFound": "找不到集合",
|
"error.collectionNotFound": "找不到集合",
|
||||||
"external_file": "外部檔案庫",
|
"external_file": "外部檔案庫",
|
||||||
@@ -62,44 +62,44 @@
|
|||||||
"external_read_url_tip": "可以設定您檔案庫的讀取網址,方便對使用者進行讀取權限驗證。目前可使用 {{fileId}} 變數來代表外部檔案識別碼。",
|
"external_read_url_tip": "可以設定您檔案庫的讀取網址,方便對使用者進行讀取權限驗證。目前可使用 {{fileId}} 變數來代表外部檔案識別碼。",
|
||||||
"external_url": "檔案存取網址",
|
"external_url": "檔案存取網址",
|
||||||
"feishu_dataset": "飛書知識庫",
|
"feishu_dataset": "飛書知識庫",
|
||||||
"feishu_dataset_config": "配置飛書知識庫",
|
"feishu_dataset_config": "設定飛書知識庫",
|
||||||
"feishu_dataset_desc": "可通過配置飛書文檔權限,使用飛書文檔構建知識庫,文檔不會進行二次存儲",
|
"feishu_dataset_desc": "可透過設定飛書文件權限,使用飛書文件建構知識庫,文件不會進行二次儲存",
|
||||||
"file_list": "文件列表",
|
"file_list": "文件列表",
|
||||||
"file_model_function_tip": "用於增強索引和問答生成",
|
"file_model_function_tip": "用於增強索引和問答生成",
|
||||||
"filename": "檔案名稱",
|
"filename": "檔案名稱",
|
||||||
"folder_dataset": "資料夾",
|
"folder_dataset": "資料夾",
|
||||||
"image_auto_parse": "圖片自動索引",
|
"image_auto_parse": "圖片自動索引",
|
||||||
"image_auto_parse_tips": "調用 VLM 自動標註文檔裡的圖片,並生成額外的檢索索引",
|
"image_auto_parse_tips": "呼叫 VLM 自動標註文件裡的圖片,並生成額外的檢索索引",
|
||||||
"image_training_queue": "圖片處理排隊",
|
"image_training_queue": "圖片處理排隊",
|
||||||
"immediate_sync": "立即同步",
|
"immediate_sync": "立即同步",
|
||||||
"import.Auto mode Estimated Price Tips": "需呼叫文字理解模型,將消耗較多 AI 點數:{{price}} 點數 / 1K tokens",
|
"import.Auto mode Estimated Price Tips": "需呼叫文字理解模型,將消耗較多 AI 點數:{{price}} 點數 / 1K tokens",
|
||||||
"import.Embedding Estimated Price Tips": "僅使用索引模型,消耗少量 AI 點數:{{price}} 點數 / 1K tokens",
|
"import.Embedding Estimated Price Tips": "僅使用索引模型,消耗少量 AI 點數:{{price}} 點數 / 1K tokens",
|
||||||
"import_confirm": "確認上傳",
|
"import_confirm": "確認上傳",
|
||||||
"import_data_preview": "數據預覽",
|
"import_data_preview": "資料預覽",
|
||||||
"import_data_process_setting": "數據處理方式設置",
|
"import_data_process_setting": "資料處理方式設定",
|
||||||
"import_file_parse_setting": "文件解析設置",
|
"import_file_parse_setting": "文件解析設定",
|
||||||
"import_model_config": "模型選擇",
|
"import_model_config": "模型選擇",
|
||||||
"import_param_setting": "參數設置",
|
"import_param_setting": "參數設定",
|
||||||
"import_select_file": "選擇文件",
|
"import_select_file": "選擇文件",
|
||||||
"import_select_link": "輸入鏈接",
|
"import_select_link": "輸入連結",
|
||||||
"index_size": "索引大小",
|
"index_size": "索引大小",
|
||||||
"index_size_tips": "向量化時內容的長度,系統會自動按該大小對分塊進行進一步的分割。",
|
"index_size_tips": "向量化時內容的長度,系統會自動按該大小對分塊進行進一步的分割。",
|
||||||
"is_open_schedule": "啟用定時同步",
|
"is_open_schedule": "啟用定時同步",
|
||||||
"keep_image": "保留圖片",
|
"keep_image": "保留圖片",
|
||||||
"move.hint": "移動後,所選資料集/資料夾將繼承新資料夾的權限設定,原先的權限設定將失效。",
|
"move.hint": "移動後,所選資料集/資料夾將繼承新資料夾的權限設定,原先的權限設定將失效。",
|
||||||
"open_auto_sync": "開啟定時同步後,系統將每天不定時嘗試同步集合,集合同步期間,會出現無法搜尋到該集合資料現象。",
|
"open_auto_sync": "開啟定時同步後,系統將每天不定時嘗試同步集合,集合同步期間,會出現無法搜尋到該集合資料現象。",
|
||||||
"params_config": "配置",
|
"params_config": "設定",
|
||||||
"params_setting": "參數設置",
|
"params_setting": "參數設定",
|
||||||
"pdf_enhance_parse": "PDF增強解析",
|
"pdf_enhance_parse": "PDF 增強解析",
|
||||||
"pdf_enhance_parse_price": "{{price}}積分/頁",
|
"pdf_enhance_parse_price": "{{price}}積分/頁",
|
||||||
"pdf_enhance_parse_tips": "調用 PDF 識別模型進行解析,可以將其轉換成 Markdown 並保留文檔中的圖片,同時也可以對掃描件進行識別,識別時間較長。",
|
"pdf_enhance_parse_tips": "呼叫 PDF 識別模型進行解析,可以將其轉換成 Markdown 並保留文件中的圖片,同時也可以對掃描件進行識別,識別時間較長。",
|
||||||
"permission.des.manage": "可管理整個資料集的資料和資訊",
|
"permission.des.manage": "可管理整個資料集的資料和資訊",
|
||||||
"permission.des.read": "可檢視資料集內容",
|
"permission.des.read": "可檢視資料集內容",
|
||||||
"permission.des.write": "可新增和變更資料集內容",
|
"permission.des.write": "可新增和變更資料集內容",
|
||||||
"preview_chunk": "分塊預覽",
|
"preview_chunk": "分塊預覽",
|
||||||
"preview_chunk_empty": "文件內容為空",
|
"preview_chunk_empty": "文件內容為空",
|
||||||
"preview_chunk_intro": "共 {{total}} 個分塊,最多展示 10 個",
|
"preview_chunk_intro": "共 {{total}} 個分塊,最多展示 10 個",
|
||||||
"preview_chunk_not_selected": "點擊左側文件後進行預覽",
|
"preview_chunk_not_selected": "點選左側文件後進行預覽",
|
||||||
"process.Auto_Index": "自動索引生成",
|
"process.Auto_Index": "自動索引生成",
|
||||||
"process.Get QA": "問答對提取",
|
"process.Get QA": "問答對提取",
|
||||||
"process.Image_Index": "圖片索引生成",
|
"process.Image_Index": "圖片索引生成",
|
||||||
@@ -119,13 +119,13 @@
|
|||||||
"split_sign_break2": "2 個換行符",
|
"split_sign_break2": "2 個換行符",
|
||||||
"split_sign_custom": "自定義",
|
"split_sign_custom": "自定義",
|
||||||
"split_sign_exclamatiob": "驚嘆號",
|
"split_sign_exclamatiob": "驚嘆號",
|
||||||
"split_sign_null": "不設置",
|
"split_sign_null": "不設定",
|
||||||
"split_sign_period": "句號",
|
"split_sign_period": "句號",
|
||||||
"split_sign_question": "問號",
|
"split_sign_question": "問號",
|
||||||
"split_sign_semicolon": "分號",
|
"split_sign_semicolon": "分號",
|
||||||
"start_sync_website_tip": "確認開始同步資料?\n將會刪除舊資料後重新獲取,請確認!",
|
"start_sync_website_tip": "確認開始同步資料?\n將會刪除舊資料後重新取得,請確認!",
|
||||||
"status_error": "運行異常",
|
"status_error": "執行異常",
|
||||||
"sync_collection_failed": "同步集合錯誤,請檢查是否能正常存取來源文件",
|
"sync_collection_failed": "同步集合錯誤,請檢查是否能正常存取來原始檔",
|
||||||
"sync_schedule": "定時同步",
|
"sync_schedule": "定時同步",
|
||||||
"sync_schedule_tip": "只會同步已存在的集合。\n包括連結集合以及 API 知識庫裡所有集合。\n系統會每天進行輪詢更新,無法確定特定的更新時間。",
|
"sync_schedule_tip": "只會同步已存在的集合。\n包括連結集合以及 API 知識庫裡所有集合。\n系統會每天進行輪詢更新,無法確定特定的更新時間。",
|
||||||
"tag.Add New": "新增",
|
"tag.Add New": "新增",
|
||||||
@@ -144,12 +144,12 @@
|
|||||||
"training.Normal": "正常",
|
"training.Normal": "正常",
|
||||||
"training_mode": "分段模式",
|
"training_mode": "分段模式",
|
||||||
"training_ready": "{{count}} 組",
|
"training_ready": "{{count}} 組",
|
||||||
"vector_model_max_tokens_tip": "每個分塊數據,最大長度為 3000 tokens",
|
"vector_model_max_tokens_tip": "每個分塊資料,最大長度為 3000 tokens",
|
||||||
"vllm_model": "圖片理解模型",
|
"vllm_model": "圖片理解模型",
|
||||||
"website_dataset": "網站同步",
|
"website_dataset": "網站同步",
|
||||||
"website_dataset_desc": "網站同步功能讓您可以直接使用網頁連結建立資料集",
|
"website_dataset_desc": "網站同步功能讓您可以直接使用網頁連結建立資料集",
|
||||||
"website_info": "網站資訊",
|
"website_info": "網站資訊",
|
||||||
"yuque_dataset": "語雀知識庫",
|
"yuque_dataset": "語雀知識庫",
|
||||||
"yuque_dataset_config": "配置語雀知識庫",
|
"yuque_dataset_config": "設定語雀知識庫",
|
||||||
"yuque_dataset_desc": "可通過配置語雀文檔權限,使用語雀文檔構建知識庫,文檔不會進行二次存儲"
|
"yuque_dataset_desc": "可透過設定語雀文件權限,使用語雀文件建構知識庫,文件不會進行二次儲存"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
"login_success": "登入成功",
|
"login_success": "登入成功",
|
||||||
"no_remind": "不再提醒",
|
"no_remind": "不再提醒",
|
||||||
"password_condition": "密碼最多 60 個字元",
|
"password_condition": "密碼最多 60 個字元",
|
||||||
"password_tip": "密碼至少 6 位,且至少包含兩種組合:數字、字母或特殊字符",
|
"password_tip": "密碼至少 6 位,且至少包含兩種組合:數字、字母或特殊字元",
|
||||||
"policy_tip": "使用即代表您同意我們的",
|
"policy_tip": "使用即代表您同意我們的",
|
||||||
"privacy": "隱私權政策",
|
"privacy": "隱私權政策",
|
||||||
"privacy_policy": "隱私權政策",
|
"privacy_policy": "隱私權政策",
|
||||||
|
|||||||
@@ -55,7 +55,7 @@
|
|||||||
"permission.only_collaborators": "僅協作者可存取",
|
"permission.only_collaborators": "僅協作者可存取",
|
||||||
"permission.team_read": "團隊可存取",
|
"permission.team_read": "團隊可存取",
|
||||||
"permission.team_write": "團隊可編輯",
|
"permission.team_write": "團隊可編輯",
|
||||||
"permission_add_tip": "添加後,您可為其勾選權限。",
|
"permission_add_tip": "新增後,您可為其勾選權限。",
|
||||||
"permission_des.manage": "可建立資源、邀請及刪除成員",
|
"permission_des.manage": "可建立資源、邀請及刪除成員",
|
||||||
"permission_des.read": "成員僅能閱讀相關資源,無法建立新資源",
|
"permission_des.read": "成員僅能閱讀相關資源,無法建立新資源",
|
||||||
"permission_des.write": "除了可讀取資源外,還可以建立新的資源",
|
"permission_des.write": "除了可讀取資源外,還可以建立新的資源",
|
||||||
@@ -75,7 +75,7 @@
|
|||||||
"synchronization.title": "填寫標籤同步連結,點選同步按鈕即可同步",
|
"synchronization.title": "填寫標籤同步連結,點選同步按鈕即可同步",
|
||||||
"team.Add manager": "新增管理員",
|
"team.Add manager": "新增管理員",
|
||||||
"team.Confirm Invite": "確認邀請",
|
"team.Confirm Invite": "確認邀請",
|
||||||
"team.Create Team": "創建新團隊",
|
"team.Create Team": "建立新團隊",
|
||||||
"team.Invite Member Failed Tip": "邀請成員出現異常",
|
"team.Invite Member Failed Tip": "邀請成員出現異常",
|
||||||
"team.Invite Member Result Tip": "邀請結果提示",
|
"team.Invite Member Result Tip": "邀請結果提示",
|
||||||
"team.Invite Member Success Tip": "邀請成員完成\n\n成功:{{success}} 人\n\n使用者名稱無效:{{inValid}}\n\n已在團隊中:{{inTeam}}",
|
"team.Invite Member Success Tip": "邀請成員完成\n\n成功:{{success}} 人\n\n使用者名稱無效:{{inValid}}\n\n已在團隊中:{{inTeam}}",
|
||||||
@@ -97,10 +97,9 @@
|
|||||||
"team.group.group": "群組",
|
"team.group.group": "群組",
|
||||||
"team.group.keep_admin": "保留管理員權限",
|
"team.group.keep_admin": "保留管理員權限",
|
||||||
"team.group.manage_member": "管理成員",
|
"team.group.manage_member": "管理成員",
|
||||||
"team.group.manage_tip": "可以管理成員、創建群組、管理所有群組、為群組和成員分配權限",
|
"team.group.manage_tip": "可以管理成員、建立群組、管理所有群組、為群組和成員分配權限",
|
||||||
"team.group.members": "成員",
|
"team.group.members": "成員",
|
||||||
"team.group.name": "群組名稱",
|
"team.group.name": "群組名稱",
|
||||||
"team.group.permission.manage": "管理員",
|
|
||||||
"team.group.permission.write": "工作臺/知識庫建立",
|
"team.group.permission.write": "工作臺/知識庫建立",
|
||||||
"team.group.permission_tip": "單獨設定權限的成員,將依照個人權限設定,不再受群組權限影響。\n若成員屬於多個權限群組,該成員的權限將會合併。",
|
"team.group.permission_tip": "單獨設定權限的成員,將依照個人權限設定,不再受群組權限影響。\n若成員屬於多個權限群組,該成員的權限將會合併。",
|
||||||
"team.group.role.admin": "管理員",
|
"team.group.role.admin": "管理員",
|
||||||
@@ -112,5 +111,6 @@
|
|||||||
"team.manage_collaborators": "管理協作者",
|
"team.manage_collaborators": "管理協作者",
|
||||||
"team.no_collaborators": "目前沒有協作者",
|
"team.no_collaborators": "目前沒有協作者",
|
||||||
"team.org.org": "組織",
|
"team.org.org": "組織",
|
||||||
"team.write_role_member": "可寫入權限"
|
"team.write_role_member": "可寫入權限",
|
||||||
|
"team.collaborator.added": "已新增"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,13 +14,13 @@
|
|||||||
"application_call": "應用程式呼叫",
|
"application_call": "應用程式呼叫",
|
||||||
"assigned_reply": "指定回覆",
|
"assigned_reply": "指定回覆",
|
||||||
"auth_tmb_id": "使用者鑑權",
|
"auth_tmb_id": "使用者鑑權",
|
||||||
"auth_tmb_id_tip": "開啟後,對外發布應用程式時,也會根據使用者是否有該知識庫權限進行知識庫過濾。\n\n若未開啟,則直接按配置的知識庫進行檢索,不進行權限過濾。",
|
"auth_tmb_id_tip": "開啟後,對外發布應用程式時,也會根據使用者是否有該知識庫權限進行知識庫過濾。\n\n若未開啟,則直接按設定的知識庫進行檢索,不進行權限過濾。",
|
||||||
"can_not_loop": "這個節點不能迴圈。",
|
"can_not_loop": "這個節點不能迴圈。",
|
||||||
"choose_another_application_to_call": "選擇另一個應用程式來呼叫",
|
"choose_another_application_to_call": "選擇另一個應用程式來呼叫",
|
||||||
"classification_result": "分類結果",
|
"classification_result": "分類結果",
|
||||||
"code.Reset template": "重設範本",
|
"code.Reset template": "重設範本",
|
||||||
"code.Reset template confirm": "確定要重設程式碼範本嗎?這將會把所有輸入和輸出重設為範本值。請儲存您目前的程式碼。",
|
"code.Reset template confirm": "確定要重設程式碼範本嗎?這將會把所有輸入和輸出重設為範本值。請儲存您目前的程式碼。",
|
||||||
"code.Switch language confirm": "切換語言將重置代碼,是否繼續?",
|
"code.Switch language confirm": "切換語言將重設代碼,是否繼續?",
|
||||||
"code_execution": "程式碼執行",
|
"code_execution": "程式碼執行",
|
||||||
"collection_metadata_filter": "資料集詮釋資料篩選器",
|
"collection_metadata_filter": "資料集詮釋資料篩選器",
|
||||||
"complete_extraction_result": "完整擷取結果",
|
"complete_extraction_result": "完整擷取結果",
|
||||||
@@ -52,7 +52,7 @@
|
|||||||
"execution_error": "執行錯誤",
|
"execution_error": "執行錯誤",
|
||||||
"extraction_requirements_description": "擷取需求描述",
|
"extraction_requirements_description": "擷取需求描述",
|
||||||
"extraction_requirements_description_detail": "提供 AI 相對應的背景知識或需求描述,引導 AI 更好地完成任務。\\n這個輸入框可以使用全域變數。",
|
"extraction_requirements_description_detail": "提供 AI 相對應的背景知識或需求描述,引導 AI 更好地完成任務。\\n這個輸入框可以使用全域變數。",
|
||||||
"extraction_requirements_placeholder": "例如: 1. 目前時間為: {{cTime}}。\n你是實驗室預約助手,你的任務是幫助使用者預約實驗室,從文字中取得對應的預約資訊。\n\n2. 你是Google搜尋助手,需要從文字中提取出合適的搜尋字詞。",
|
"extraction_requirements_placeholder": "例如:1. 目前時間為:{{cTime}}。\n你是實驗室預約助手,你的任務是幫助使用者預約實驗室,從文字中取得對應的預約資訊。\n\n2. 你是 Google 搜尋助手,需要從文字中提取出合適的搜尋字詞。",
|
||||||
"feedback_text": "回饋文字",
|
"feedback_text": "回饋文字",
|
||||||
"field_description": "欄位描述",
|
"field_description": "欄位描述",
|
||||||
"field_description_placeholder": "描述這個輸入欄位的功能,如果是工具呼叫參數,這個描述會影響模型產生的品質",
|
"field_description_placeholder": "描述這個輸入欄位的功能,如果是工具呼叫參數,這個描述會影響模型產生的品質",
|
||||||
@@ -84,7 +84,7 @@
|
|||||||
"intro_http_request": "可以傳送 HTTP 請求,執行更複雜的操作(網路搜尋、資料庫查詢等等)",
|
"intro_http_request": "可以傳送 HTTP 請求,執行更複雜的操作(網路搜尋、資料庫查詢等等)",
|
||||||
"intro_knowledge_base_search_merge": "可以合併多個知識庫搜尋結果並輸出。使用 RRF 合併方法進行最終排序輸出。",
|
"intro_knowledge_base_search_merge": "可以合併多個知識庫搜尋結果並輸出。使用 RRF 合併方法進行最終排序輸出。",
|
||||||
"intro_laf_function_call": "可以呼叫 Laf 帳號下的雲端函式。",
|
"intro_laf_function_call": "可以呼叫 Laf 帳號下的雲端函式。",
|
||||||
"intro_loop": "輸入一個數組,遍歷數組並將每個數組元素作為輸入元素,執行工作流程。",
|
"intro_loop": "輸入一個陣列,遍歷陣列並將每個陣列元素作為輸入元素,執行工作流程。",
|
||||||
"intro_plugin_input": "可以設定外掛程式需要的輸入,並利用這些輸入來執行外掛程式",
|
"intro_plugin_input": "可以設定外掛程式需要的輸入,並利用這些輸入來執行外掛程式",
|
||||||
"intro_question_classification": "根據使用者的歷史紀錄和目前問題判斷這次提問的類型。可以新增多個問題類型,以下是一個範例:\n類型 1:打招呼\n類型 2:關於產品「使用方式」的問題\n類型 3:關於產品「購買」的問題\n類型 4:其他問題",
|
"intro_question_classification": "根據使用者的歷史紀錄和目前問題判斷這次提問的類型。可以新增多個問題類型,以下是一個範例:\n類型 1:打招呼\n類型 2:關於產品「使用方式」的問題\n類型 3:關於產品「購買」的問題\n類型 4:其他問題",
|
||||||
"intro_question_optimization": "使用問題最佳化功能,可以提升知識庫連續對話時的搜尋精準度。使用這個功能後,會先利用 AI 根據脈絡建構一個或多個新的檢索詞彙,這些詞彙更有利於知識庫搜尋。這個模組已內建於知識庫搜尋模組中,如果您只進行一次知識庫搜尋,可以直接使用知識庫內建的自動完成功能。",
|
"intro_question_optimization": "使用問題最佳化功能,可以提升知識庫連續對話時的搜尋精準度。使用這個功能後,會先利用 AI 根據脈絡建構一個或多個新的檢索詞彙,這些詞彙更有利於知識庫搜尋。這個模組已內建於知識庫搜尋模組中,如果您只進行一次知識庫搜尋,可以直接使用知識庫內建的自動完成功能。",
|
||||||
@@ -134,7 +134,7 @@
|
|||||||
"question_classification": "問題分類",
|
"question_classification": "問題分類",
|
||||||
"question_optimization": "問題最佳化",
|
"question_optimization": "問題最佳化",
|
||||||
"quote_content_placeholder": "可以自訂引用內容的結構,以便更好地適應不同場景。可以使用一些變數來設定範本\n{{q}} - 主要內容\n{{a}} - 輔助資料\n{{source}} - 來源名稱\n{{sourceId}} - 來源 ID\n{{index}} - 第 n 個引用",
|
"quote_content_placeholder": "可以自訂引用內容的結構,以便更好地適應不同場景。可以使用一些變數來設定範本\n{{q}} - 主要內容\n{{a}} - 輔助資料\n{{source}} - 來源名稱\n{{sourceId}} - 來源 ID\n{{index}} - 第 n 個引用",
|
||||||
"quote_content_tip": "可以自訂引用內容的結構,以更好的適合不同場景。\n可以使用一些變數來進行模板配置\n\n{{id}} - 引用資料唯一id\n\n{{q}} - 主要內容\n\n{{a}} - 輔助數據\n\n{{source}} - 來源名\n\n{{sourceId}} - 來源ID\n\n{{index}} - 第 n 個引用\n\n他們都是可選的,下面是預設值:\n\n{{default}}",
|
"quote_content_tip": "可以自訂引用內容的結構,以更好的適合不同場景。\n可以使用一些變數來進行範本設定\n\n{{id}} - 引用資料唯一 id\n\n{{q}} - 主要內容\n\n{{a}} - 輔助資料\n\n{{source}} - 來源名\n\n{{sourceId}} - 來源 ID\n\n{{index}} - 第 n 個引用\n\n他們都是可選的,下面是預設值:\n\n{{default}}",
|
||||||
"quote_num": "引用數量",
|
"quote_num": "引用數量",
|
||||||
"quote_prompt_tip": "可以使用 {{quote}} 來插入引用內容範本,使用 {{question}} 來插入問題(Role=user)。\n以下是預設值:\n{{default}}",
|
"quote_prompt_tip": "可以使用 {{quote}} 來插入引用內容範本,使用 {{question}} 來插入問題(Role=user)。\n以下是預設值:\n{{default}}",
|
||||||
"quote_role_system_tip": "請注意從「引用範本提示詞」中移除 {{question}} 變數",
|
"quote_role_system_tip": "請注意從「引用範本提示詞」中移除 {{question}} 變數",
|
||||||
@@ -154,7 +154,7 @@
|
|||||||
"select_another_application_to_call": "可以選擇另一個應用程式來呼叫",
|
"select_another_application_to_call": "可以選擇另一個應用程式來呼叫",
|
||||||
"special_array_format": "特殊陣列格式,搜尋結果為空時,回傳空陣列。",
|
"special_array_format": "特殊陣列格式,搜尋結果為空時,回傳空陣列。",
|
||||||
"start_with": "開頭為",
|
"start_with": "開頭為",
|
||||||
"support_code_language": "支持import列表:pandas,numpy",
|
"support_code_language": "支援 import 列表:pandas,numpy",
|
||||||
"target_fields_description": "由「描述」和「鍵值」組成一個目標欄位,可以擷取多個目標欄位",
|
"target_fields_description": "由「描述」和「鍵值」組成一個目標欄位,可以擷取多個目標欄位",
|
||||||
"template.ai_chat": "AI 對話",
|
"template.ai_chat": "AI 對話",
|
||||||
"template.ai_chat_intro": "AI 大型語言模型對話",
|
"template.ai_chat_intro": "AI 大型語言模型對話",
|
||||||
|
|||||||
@@ -1,79 +0,0 @@
|
|||||||
diff --git a/lib/index.js b/lib/index.js
|
|
||||||
index c5ca771c24dd914e342f791716a822431ee32b3a..457d9f8c4625f7d9c7ea1e9ffc13616db1fc6fef 100644
|
|
||||||
--- a/lib/index.js
|
|
||||||
+++ b/lib/index.js
|
|
||||||
@@ -126,8 +126,37 @@ function exitLiteralAutolink(token) {
|
|
||||||
this.exit(token)
|
|
||||||
}
|
|
||||||
|
|
||||||
-/** @type {FromMarkdownTransform} */
|
|
||||||
+// Regex support detector, for backward compatibility
|
|
||||||
+// Ref: https://github.com/syntax-tree/mdast-util-gfm-autolink-literal/pull/14
|
|
||||||
+const regexSupport = {
|
|
||||||
+ lookbehind: (() => {
|
|
||||||
+ try {
|
|
||||||
+ // Using regex literal instead of RegExp constructor
|
|
||||||
+ ;/(?<=x)/.test('x')
|
|
||||||
+ return true
|
|
||||||
+ } catch {
|
|
||||||
+ return false
|
|
||||||
+ }
|
|
||||||
+ })()
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+/**
|
|
||||||
+ * Main transform function that uses the appropriate version based on regex support
|
|
||||||
+ * @type {FromMarkdownTransform}
|
|
||||||
+ */
|
|
||||||
function transformGfmAutolinkLiterals(tree) {
|
|
||||||
+ if (regexSupport.lookbehind) {
|
|
||||||
+ modernAutolinkTransform(tree)
|
|
||||||
+ } else {
|
|
||||||
+ legacyAutolinkTransform(tree)
|
|
||||||
+ }
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+/**
|
|
||||||
+ * Modern version of autolink transform using lookbehind
|
|
||||||
+ * @type {FromMarkdownTransform}
|
|
||||||
+ */
|
|
||||||
+function modernAutolinkTransform(tree) {
|
|
||||||
findAndReplace(
|
|
||||||
tree,
|
|
||||||
[
|
|
||||||
@@ -138,6 +167,35 @@ function transformGfmAutolinkLiterals(tree) {
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
+
|
|
||||||
+/**
|
|
||||||
+ * Legacy version of autolink transform for older Node.js versions
|
|
||||||
+ * @type {FromMarkdownTransform}
|
|
||||||
+ */
|
|
||||||
+function legacyAutolinkTransform(tree) {
|
|
||||||
+ findAndReplace(
|
|
||||||
+ tree,
|
|
||||||
+ [
|
|
||||||
+ [/(https?:\/\/|www(?=\.))([-.\w]+)([^ \t\r\n]*)/gi, findUrl],
|
|
||||||
+ // [/([-.\w+]+)@([-\w]+(?:\.[-\w]+)+)/g, findEmail] # NOTE: original regex in 2.0.0
|
|
||||||
+ [/(^|\s|\p{P}|\p{S})([-.\w+]+)@([-\w]+(?:\.[-\w]+)+)/gu, findEmailLegacy]
|
|
||||||
+ ],
|
|
||||||
+ {ignore: ['link', 'linkReference']}
|
|
||||||
+ )
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
+/**
|
|
||||||
+ * Helper function for legacy email matching
|
|
||||||
+ * @param {string} _ - Unused parameter
|
|
||||||
+ * @param {string} prefix - Email prefix
|
|
||||||
+ * @param {string} name - Email name
|
|
||||||
+ * @param {string} domain - Email domain
|
|
||||||
+ * @returns {*} The processed email
|
|
||||||
+ */
|
|
||||||
+function findEmailLegacy(_, prefix, name, domain) {
|
|
||||||
+ return findEmail(name + '@' + domain)
|
|
||||||
+}
|
|
||||||
+
|
|
||||||
/**
|
|
||||||
* @type {ReplaceFunction}
|
|
||||||
* @param {string} _
|
|
||||||
233
pnpm-lock.yaml
generated
233
pnpm-lock.yaml
generated
@@ -4,10 +4,8 @@ settings:
|
|||||||
autoInstallPeers: true
|
autoInstallPeers: true
|
||||||
excludeLinksFromLockfile: false
|
excludeLinksFromLockfile: false
|
||||||
|
|
||||||
patchedDependencies:
|
overrides:
|
||||||
mdast-util-gfm-autolink-literal@2.0.1:
|
mdast-util-gfm-autolink-literal: 2.0.0
|
||||||
hash: f63d515781110436299ab612306211a9621c6dfaec1ce1a19e2f27454dc70251
|
|
||||||
path: patches/mdast-util-gfm-autolink-literal@2.0.1.patch
|
|
||||||
|
|
||||||
importers:
|
importers:
|
||||||
|
|
||||||
@@ -17,8 +15,8 @@ importers:
|
|||||||
specifier: ^2.4.1
|
specifier: ^2.4.1
|
||||||
version: 2.5.8(encoding@0.1.13)(react@18.3.1)
|
version: 2.5.8(encoding@0.1.13)(react@18.3.1)
|
||||||
'@vitest/coverage-v8':
|
'@vitest/coverage-v8':
|
||||||
specifier: ^3.0.2
|
specifier: ^3.0.9
|
||||||
version: 3.0.8(vitest@3.0.8(@types/debug@4.1.12)(@types/node@20.17.24)(sass@1.85.1)(terser@5.39.0))
|
version: 3.1.1(vitest@3.1.1(@types/debug@4.1.12)(@types/node@20.17.24)(sass@1.85.1)(terser@5.39.0))
|
||||||
husky:
|
husky:
|
||||||
specifier: ^8.0.3
|
specifier: ^8.0.3
|
||||||
version: 8.0.3
|
version: 8.0.3
|
||||||
@@ -28,9 +26,12 @@ importers:
|
|||||||
lint-staged:
|
lint-staged:
|
||||||
specifier: ^13.3.0
|
specifier: ^13.3.0
|
||||||
version: 13.3.0
|
version: 13.3.0
|
||||||
|
mongodb-memory-server:
|
||||||
|
specifier: ^10.1.4
|
||||||
|
version: 10.1.4(socks@2.8.4)
|
||||||
next-i18next:
|
next-i18next:
|
||||||
specifier: 15.4.2
|
specifier: 15.4.2
|
||||||
version: 15.4.2(i18next@23.16.8)(next@14.2.26(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.85.1))(react-i18next@14.1.2(i18next@23.16.8)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)
|
version: 15.4.2(i18next@23.16.8)(next@14.2.26(@babel/core@7.26.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.85.1))(react-i18next@14.1.2(i18next@23.16.8)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)
|
||||||
prettier:
|
prettier:
|
||||||
specifier: 3.2.4
|
specifier: 3.2.4
|
||||||
version: 3.2.4
|
version: 3.2.4
|
||||||
@@ -38,11 +39,8 @@ importers:
|
|||||||
specifier: 14.1.2
|
specifier: 14.1.2
|
||||||
version: 14.1.2(i18next@23.16.8)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
version: 14.1.2(i18next@23.16.8)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||||
vitest:
|
vitest:
|
||||||
specifier: ^3.0.2
|
specifier: ^3.0.9
|
||||||
version: 3.0.8(@types/debug@4.1.12)(@types/node@20.17.24)(sass@1.85.1)(terser@5.39.0)
|
version: 3.1.1(@types/debug@4.1.12)(@types/node@20.17.24)(sass@1.85.1)(terser@5.39.0)
|
||||||
vitest-mongodb:
|
|
||||||
specifier: ^1.0.1
|
|
||||||
version: 1.0.1(socks@2.8.4)
|
|
||||||
zhlint:
|
zhlint:
|
||||||
specifier: ^0.7.4
|
specifier: ^0.7.4
|
||||||
version: 0.7.4(@types/node@20.17.24)(sass@1.85.1)(terser@5.39.0)(typescript@5.8.2)
|
version: 0.7.4(@types/node@20.17.24)(sass@1.85.1)(terser@5.39.0)(typescript@5.8.2)
|
||||||
@@ -327,7 +325,7 @@ importers:
|
|||||||
version: 2.1.1(@chakra-ui/system@2.6.1(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(@types/react@18.3.1)(react@18.3.1))(react@18.3.1))(react@18.3.1)
|
version: 2.1.1(@chakra-ui/system@2.6.1(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(@types/react@18.3.1)(react@18.3.1))(react@18.3.1))(react@18.3.1)
|
||||||
'@chakra-ui/next-js':
|
'@chakra-ui/next-js':
|
||||||
specifier: 2.4.2
|
specifier: 2.4.2
|
||||||
version: 2.4.2(@chakra-ui/react@2.10.7(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(@types/react@18.3.1)(react@18.3.1))(@types/react@18.3.1)(framer-motion@9.1.7(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(next@14.2.26(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.85.1))(react@18.3.1)
|
version: 2.4.2(@chakra-ui/react@2.10.7(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(@types/react@18.3.1)(react@18.3.1))(@types/react@18.3.1)(framer-motion@9.1.7(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(next@14.2.26(@babel/core@7.26.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.85.1))(react@18.3.1)
|
||||||
'@chakra-ui/react':
|
'@chakra-ui/react':
|
||||||
specifier: 2.10.7
|
specifier: 2.10.7
|
||||||
version: 2.10.7(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(@types/react@18.3.1)(react@18.3.1))(@types/react@18.3.1)(framer-motion@9.1.7(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
version: 2.10.7(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(@types/react@18.3.1)(react@18.3.1))(@types/react@18.3.1)(framer-motion@9.1.7(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||||
@@ -390,7 +388,7 @@ importers:
|
|||||||
version: 4.17.21
|
version: 4.17.21
|
||||||
next-i18next:
|
next-i18next:
|
||||||
specifier: 15.4.2
|
specifier: 15.4.2
|
||||||
version: 15.4.2(i18next@23.16.8)(next@14.2.26(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.85.1))(react-i18next@14.1.2(i18next@23.16.8)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)
|
version: 15.4.2(i18next@23.16.8)(next@14.2.26(@babel/core@7.26.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.85.1))(react-i18next@14.1.2(i18next@23.16.8)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)
|
||||||
papaparse:
|
papaparse:
|
||||||
specifier: ^5.4.1
|
specifier: ^5.4.1
|
||||||
version: 5.4.1
|
version: 5.4.1
|
||||||
@@ -451,7 +449,7 @@ importers:
|
|||||||
version: 2.1.1(@chakra-ui/system@2.6.1(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(@types/react@18.3.1)(react@18.3.1))(react@18.3.1))(react@18.3.1)
|
version: 2.1.1(@chakra-ui/system@2.6.1(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(@types/react@18.3.1)(react@18.3.1))(react@18.3.1))(react@18.3.1)
|
||||||
'@chakra-ui/next-js':
|
'@chakra-ui/next-js':
|
||||||
specifier: 2.4.2
|
specifier: 2.4.2
|
||||||
version: 2.4.2(@chakra-ui/react@2.10.7(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(@types/react@18.3.1)(react@18.3.1))(@types/react@18.3.1)(framer-motion@9.1.7(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(next@14.2.26(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.85.1))(react@18.3.1)
|
version: 2.4.2(@chakra-ui/react@2.10.7(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(@types/react@18.3.1)(react@18.3.1))(@types/react@18.3.1)(framer-motion@9.1.7(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(next@14.2.26(@babel/core@7.26.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.85.1))(react@18.3.1)
|
||||||
'@chakra-ui/react':
|
'@chakra-ui/react':
|
||||||
specifier: 2.10.7
|
specifier: 2.10.7
|
||||||
version: 2.10.7(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(@types/react@18.3.1)(react@18.3.1))(@types/react@18.3.1)(framer-motion@9.1.7(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
version: 2.10.7(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(@types/react@18.3.1)(react@18.3.1))(@types/react@18.3.1)(framer-motion@9.1.7(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||||
@@ -550,7 +548,7 @@ importers:
|
|||||||
version: 14.2.26(@babel/core@7.26.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.85.1)
|
version: 14.2.26(@babel/core@7.26.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.85.1)
|
||||||
next-i18next:
|
next-i18next:
|
||||||
specifier: 15.4.2
|
specifier: 15.4.2
|
||||||
version: 15.4.2(i18next@23.16.8)(next@14.2.26(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.85.1))(react-i18next@14.1.2(i18next@23.16.8)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)
|
version: 15.4.2(i18next@23.16.8)(next@14.2.26(@babel/core@7.26.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.85.1))(react-i18next@14.1.2(i18next@23.16.8)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)
|
||||||
nprogress:
|
nprogress:
|
||||||
specifier: ^0.2.0
|
specifier: ^0.2.0
|
||||||
version: 0.2.0
|
version: 0.2.0
|
||||||
@@ -3565,11 +3563,11 @@ packages:
|
|||||||
'@ungap/structured-clone@1.3.0':
|
'@ungap/structured-clone@1.3.0':
|
||||||
resolution: {integrity: sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==}
|
resolution: {integrity: sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==}
|
||||||
|
|
||||||
'@vitest/coverage-v8@3.0.8':
|
'@vitest/coverage-v8@3.1.1':
|
||||||
resolution: {integrity: sha512-y7SAKsQirsEJ2F8bulBck4DoluhI2EEgTimHd6EEUgJBGKy9tC25cpywh1MH4FvDGoG2Unt7+asVd1kj4qOSAw==}
|
resolution: {integrity: sha512-MgV6D2dhpD6Hp/uroUoAIvFqA8AuvXEFBC2eepG3WFc1pxTfdk1LEqqkWoWhjz+rytoqrnUUCdf6Lzco3iHkLQ==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
'@vitest/browser': 3.0.8
|
'@vitest/browser': 3.1.1
|
||||||
vitest: 3.0.8
|
vitest: 3.1.1
|
||||||
peerDependenciesMeta:
|
peerDependenciesMeta:
|
||||||
'@vitest/browser':
|
'@vitest/browser':
|
||||||
optional: true
|
optional: true
|
||||||
@@ -3580,6 +3578,9 @@ packages:
|
|||||||
'@vitest/expect@3.0.8':
|
'@vitest/expect@3.0.8':
|
||||||
resolution: {integrity: sha512-Xu6TTIavTvSSS6LZaA3EebWFr6tsoXPetOWNMOlc7LO88QVVBwq2oQWBoDiLCN6YTvNYsGSjqOO8CAdjom5DCQ==}
|
resolution: {integrity: sha512-Xu6TTIavTvSSS6LZaA3EebWFr6tsoXPetOWNMOlc7LO88QVVBwq2oQWBoDiLCN6YTvNYsGSjqOO8CAdjom5DCQ==}
|
||||||
|
|
||||||
|
'@vitest/expect@3.1.1':
|
||||||
|
resolution: {integrity: sha512-q/zjrW9lgynctNbwvFtQkGK9+vvHA5UzVi2V8APrp1C6fG6/MuYYkmlx4FubuqLycCeSdHD5aadWfua/Vr0EUA==}
|
||||||
|
|
||||||
'@vitest/mocker@3.0.8':
|
'@vitest/mocker@3.0.8':
|
||||||
resolution: {integrity: sha512-n3LjS7fcW1BCoF+zWZxG7/5XvuYH+lsFg+BDwwAz0arIwHQJFUEsKBQ0BLU49fCxuM/2HSeBPHQD8WjgrxMfow==}
|
resolution: {integrity: sha512-n3LjS7fcW1BCoF+zWZxG7/5XvuYH+lsFg+BDwwAz0arIwHQJFUEsKBQ0BLU49fCxuM/2HSeBPHQD8WjgrxMfow==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
@@ -3591,33 +3592,59 @@ packages:
|
|||||||
vite:
|
vite:
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
|
'@vitest/mocker@3.1.1':
|
||||||
|
resolution: {integrity: sha512-bmpJJm7Y7i9BBELlLuuM1J1Q6EQ6K5Ye4wcyOpOMXMcePYKSIYlpcrCm4l/O6ja4VJA5G2aMJiuZkZdnxlC3SA==}
|
||||||
|
peerDependencies:
|
||||||
|
msw: ^2.4.9
|
||||||
|
vite: ^5.0.0 || ^6.0.0
|
||||||
|
peerDependenciesMeta:
|
||||||
|
msw:
|
||||||
|
optional: true
|
||||||
|
vite:
|
||||||
|
optional: true
|
||||||
|
|
||||||
'@vitest/pretty-format@3.0.8':
|
'@vitest/pretty-format@3.0.8':
|
||||||
resolution: {integrity: sha512-BNqwbEyitFhzYMYHUVbIvepOyeQOSFA/NeJMIP9enMntkkxLgOcgABH6fjyXG85ipTgvero6noreavGIqfJcIg==}
|
resolution: {integrity: sha512-BNqwbEyitFhzYMYHUVbIvepOyeQOSFA/NeJMIP9enMntkkxLgOcgABH6fjyXG85ipTgvero6noreavGIqfJcIg==}
|
||||||
|
|
||||||
|
'@vitest/pretty-format@3.1.1':
|
||||||
|
resolution: {integrity: sha512-dg0CIzNx+hMMYfNmSqJlLSXEmnNhMswcn3sXO7Tpldr0LiGmg3eXdLLhwkv2ZqgHb/d5xg5F7ezNFRA1fA13yA==}
|
||||||
|
|
||||||
'@vitest/runner@1.6.1':
|
'@vitest/runner@1.6.1':
|
||||||
resolution: {integrity: sha512-3nSnYXkVkf3mXFfE7vVyPmi3Sazhb/2cfZGGs0JRzFsPFvAMBEcrweV1V1GsrstdXeKCTXlJbvnQwGWgEIHmOA==}
|
resolution: {integrity: sha512-3nSnYXkVkf3mXFfE7vVyPmi3Sazhb/2cfZGGs0JRzFsPFvAMBEcrweV1V1GsrstdXeKCTXlJbvnQwGWgEIHmOA==}
|
||||||
|
|
||||||
'@vitest/runner@3.0.8':
|
'@vitest/runner@3.0.8':
|
||||||
resolution: {integrity: sha512-c7UUw6gEcOzI8fih+uaAXS5DwjlBaCJUo7KJ4VvJcjL95+DSR1kova2hFuRt3w41KZEFcOEiq098KkyrjXeM5w==}
|
resolution: {integrity: sha512-c7UUw6gEcOzI8fih+uaAXS5DwjlBaCJUo7KJ4VvJcjL95+DSR1kova2hFuRt3w41KZEFcOEiq098KkyrjXeM5w==}
|
||||||
|
|
||||||
|
'@vitest/runner@3.1.1':
|
||||||
|
resolution: {integrity: sha512-X/d46qzJuEDO8ueyjtKfxffiXraPRfmYasoC4i5+mlLEJ10UvPb0XH5M9C3gWuxd7BAQhpK42cJgJtq53YnWVA==}
|
||||||
|
|
||||||
'@vitest/snapshot@1.6.1':
|
'@vitest/snapshot@1.6.1':
|
||||||
resolution: {integrity: sha512-WvidQuWAzU2p95u8GAKlRMqMyN1yOJkGHnx3M1PL9Raf7AQ1kwLKg04ADlCa3+OXUZE7BceOhVZiuWAbzCKcUQ==}
|
resolution: {integrity: sha512-WvidQuWAzU2p95u8GAKlRMqMyN1yOJkGHnx3M1PL9Raf7AQ1kwLKg04ADlCa3+OXUZE7BceOhVZiuWAbzCKcUQ==}
|
||||||
|
|
||||||
'@vitest/snapshot@3.0.8':
|
'@vitest/snapshot@3.0.8':
|
||||||
resolution: {integrity: sha512-x8IlMGSEMugakInj44nUrLSILh/zy1f2/BgH0UeHpNyOocG18M9CWVIFBaXPt8TrqVZWmcPjwfG/ht5tnpba8A==}
|
resolution: {integrity: sha512-x8IlMGSEMugakInj44nUrLSILh/zy1f2/BgH0UeHpNyOocG18M9CWVIFBaXPt8TrqVZWmcPjwfG/ht5tnpba8A==}
|
||||||
|
|
||||||
|
'@vitest/snapshot@3.1.1':
|
||||||
|
resolution: {integrity: sha512-bByMwaVWe/+1WDf9exFxWWgAixelSdiwo2p33tpqIlM14vW7PRV5ppayVXtfycqze4Qhtwag5sVhX400MLBOOw==}
|
||||||
|
|
||||||
'@vitest/spy@1.6.1':
|
'@vitest/spy@1.6.1':
|
||||||
resolution: {integrity: sha512-MGcMmpGkZebsMZhbQKkAf9CX5zGvjkBTqf8Zx3ApYWXr3wG+QvEu2eXWfnIIWYSJExIp4V9FCKDEeygzkYrXMw==}
|
resolution: {integrity: sha512-MGcMmpGkZebsMZhbQKkAf9CX5zGvjkBTqf8Zx3ApYWXr3wG+QvEu2eXWfnIIWYSJExIp4V9FCKDEeygzkYrXMw==}
|
||||||
|
|
||||||
'@vitest/spy@3.0.8':
|
'@vitest/spy@3.0.8':
|
||||||
resolution: {integrity: sha512-MR+PzJa+22vFKYb934CejhR4BeRpMSoxkvNoDit68GQxRLSf11aT6CTj3XaqUU9rxgWJFnqicN/wxw6yBRkI1Q==}
|
resolution: {integrity: sha512-MR+PzJa+22vFKYb934CejhR4BeRpMSoxkvNoDit68GQxRLSf11aT6CTj3XaqUU9rxgWJFnqicN/wxw6yBRkI1Q==}
|
||||||
|
|
||||||
|
'@vitest/spy@3.1.1':
|
||||||
|
resolution: {integrity: sha512-+EmrUOOXbKzLkTDwlsc/xrwOlPDXyVk3Z6P6K4oiCndxz7YLpp/0R0UsWVOKT0IXWjjBJuSMk6D27qipaupcvQ==}
|
||||||
|
|
||||||
'@vitest/utils@1.6.1':
|
'@vitest/utils@1.6.1':
|
||||||
resolution: {integrity: sha512-jOrrUvXM4Av9ZWiG1EajNto0u96kWAhJ1LmPmJhXXQx/32MecEKd10pOLYgS2BQx1TgkGhloPU1ArDW2vvaY6g==}
|
resolution: {integrity: sha512-jOrrUvXM4Av9ZWiG1EajNto0u96kWAhJ1LmPmJhXXQx/32MecEKd10pOLYgS2BQx1TgkGhloPU1ArDW2vvaY6g==}
|
||||||
|
|
||||||
'@vitest/utils@3.0.8':
|
'@vitest/utils@3.0.8':
|
||||||
resolution: {integrity: sha512-nkBC3aEhfX2PdtQI/QwAWp8qZWwzASsU4Npbcd5RdMPBSSLCpkZp52P3xku3s3uA0HIEhGvEcF8rNkBsz9dQ4Q==}
|
resolution: {integrity: sha512-nkBC3aEhfX2PdtQI/QwAWp8qZWwzASsU4Npbcd5RdMPBSSLCpkZp52P3xku3s3uA0HIEhGvEcF8rNkBsz9dQ4Q==}
|
||||||
|
|
||||||
|
'@vitest/utils@3.1.1':
|
||||||
|
resolution: {integrity: sha512-1XIjflyaU2k3HMArJ50bwSh3wKWPD6Q47wz/NUSmRV0zNywPc4w79ARjg/i/aNINHwA+mIALhUVqD9/aUvZNgg==}
|
||||||
|
|
||||||
'@vue/compiler-core@3.5.13':
|
'@vue/compiler-core@3.5.13':
|
||||||
resolution: {integrity: sha512-oOdAkwqUfW1WqpwSYJce06wvt6HljgY3fGeM9NcVA1HaYOij3mZG9Rkysn0OHuyUAGMbEbARIpsG+LPVlBJ5/Q==}
|
resolution: {integrity: sha512-oOdAkwqUfW1WqpwSYJce06wvt6HljgY3fGeM9NcVA1HaYOij3mZG9Rkysn0OHuyUAGMbEbARIpsG+LPVlBJ5/Q==}
|
||||||
|
|
||||||
@@ -6783,8 +6810,8 @@ packages:
|
|||||||
mdast-util-from-markdown@2.0.2:
|
mdast-util-from-markdown@2.0.2:
|
||||||
resolution: {integrity: sha512-uZhTV/8NBuw0WHkPTrCqDOl0zVe1BIng5ZtHoDk49ME1qqcjYmmLmOf0gELgcRMxN4w2iuIeVso5/6QymSrgmA==}
|
resolution: {integrity: sha512-uZhTV/8NBuw0WHkPTrCqDOl0zVe1BIng5ZtHoDk49ME1qqcjYmmLmOf0gELgcRMxN4w2iuIeVso5/6QymSrgmA==}
|
||||||
|
|
||||||
mdast-util-gfm-autolink-literal@2.0.1:
|
mdast-util-gfm-autolink-literal@2.0.0:
|
||||||
resolution: {integrity: sha512-5HVP2MKaP6L+G6YaxPNjuL0BPrq9orG3TsrZ9YXbA3vDw/ACI4MEsnoDpn6ZNm7GnZgtAcONJyPhOP8tNJQavQ==}
|
resolution: {integrity: sha512-FyzMsduZZHSc3i0Px3PQcBT4WJY/X/RCtEJKuybiC6sjPqLv7h1yqAkmILZtuxMSsUyaLUWNp71+vQH2zqp5cg==}
|
||||||
|
|
||||||
mdast-util-gfm-footnote@2.1.0:
|
mdast-util-gfm-footnote@2.1.0:
|
||||||
resolution: {integrity: sha512-sqpDWlsHn7Ac9GNZQMeUzPQSMzR6Wv0WKRNvQRg0KqHh02fpTz69Qc1QSseNX29bhz1ROIyNyxExfawVKTm1GQ==}
|
resolution: {integrity: sha512-sqpDWlsHn7Ac9GNZQMeUzPQSMzR6Wv0WKRNvQRg0KqHh02fpTz69Qc1QSseNX29bhz1ROIyNyxExfawVKTm1GQ==}
|
||||||
@@ -9330,6 +9357,11 @@ packages:
|
|||||||
engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0}
|
engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
|
|
||||||
|
vite-node@3.1.1:
|
||||||
|
resolution: {integrity: sha512-V+IxPAE2FvXpTCHXyNem0M+gWm6J7eRyWPR6vYoG/Gl+IscNOjXzztUhimQgTxaAoUoj40Qqimaa0NLIOOAH4w==}
|
||||||
|
engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0}
|
||||||
|
hasBin: true
|
||||||
|
|
||||||
vite@5.4.14:
|
vite@5.4.14:
|
||||||
resolution: {integrity: sha512-EK5cY7Q1D8JNhSaPKVK4pwBFvaTmZxEnoKXLG/U9gmdDcihQGNzFlgIvaxezFR4glP1LsuiedwMBqCXH3wZccA==}
|
resolution: {integrity: sha512-EK5cY7Q1D8JNhSaPKVK4pwBFvaTmZxEnoKXLG/U9gmdDcihQGNzFlgIvaxezFR4glP1LsuiedwMBqCXH3wZccA==}
|
||||||
engines: {node: ^18.0.0 || >=20.0.0}
|
engines: {node: ^18.0.0 || >=20.0.0}
|
||||||
@@ -9401,9 +9433,6 @@ packages:
|
|||||||
yaml:
|
yaml:
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
vitest-mongodb@1.0.1:
|
|
||||||
resolution: {integrity: sha512-a9Mc2F35h8qxI1uOgsrCUH28TglClAd8gdXkn7CBqmC6bLr6D2Ibyxp0Xz6/AU0ukAOfuf/6oqUS+ZN0VlxVyQ==}
|
|
||||||
|
|
||||||
vitest@1.6.1:
|
vitest@1.6.1:
|
||||||
resolution: {integrity: sha512-Ljb1cnSJSivGN0LqXd/zmDbWEM0RNNg2t1QW/XUhYl/qPqyu7CsqeWtqQXHVaJsecLPuDoak2oJcZN2QoRIOag==}
|
resolution: {integrity: sha512-Ljb1cnSJSivGN0LqXd/zmDbWEM0RNNg2t1QW/XUhYl/qPqyu7CsqeWtqQXHVaJsecLPuDoak2oJcZN2QoRIOag==}
|
||||||
engines: {node: ^18.0.0 || >=20.0.0}
|
engines: {node: ^18.0.0 || >=20.0.0}
|
||||||
@@ -9457,6 +9486,34 @@ packages:
|
|||||||
jsdom:
|
jsdom:
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
|
vitest@3.1.1:
|
||||||
|
resolution: {integrity: sha512-kiZc/IYmKICeBAZr9DQ5rT7/6bD9G7uqQEki4fxazi1jdVl2mWGzedtBs5s6llz59yQhVb7FFY2MbHzHCnT79Q==}
|
||||||
|
engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0}
|
||||||
|
hasBin: true
|
||||||
|
peerDependencies:
|
||||||
|
'@edge-runtime/vm': '*'
|
||||||
|
'@types/debug': ^4.1.12
|
||||||
|
'@types/node': ^18.0.0 || ^20.0.0 || >=22.0.0
|
||||||
|
'@vitest/browser': 3.1.1
|
||||||
|
'@vitest/ui': 3.1.1
|
||||||
|
happy-dom: '*'
|
||||||
|
jsdom: '*'
|
||||||
|
peerDependenciesMeta:
|
||||||
|
'@edge-runtime/vm':
|
||||||
|
optional: true
|
||||||
|
'@types/debug':
|
||||||
|
optional: true
|
||||||
|
'@types/node':
|
||||||
|
optional: true
|
||||||
|
'@vitest/browser':
|
||||||
|
optional: true
|
||||||
|
'@vitest/ui':
|
||||||
|
optional: true
|
||||||
|
happy-dom:
|
||||||
|
optional: true
|
||||||
|
jsdom:
|
||||||
|
optional: true
|
||||||
|
|
||||||
void-elements@3.1.0:
|
void-elements@3.1.0:
|
||||||
resolution: {integrity: sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w==}
|
resolution: {integrity: sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w==}
|
||||||
engines: {node: '>=0.10.0'}
|
engines: {node: '>=0.10.0'}
|
||||||
@@ -10740,7 +10797,7 @@ snapshots:
|
|||||||
'@chakra-ui/system': 2.6.1(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(@types/react@18.3.1)(react@18.3.1))(react@18.3.1)
|
'@chakra-ui/system': 2.6.1(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(@types/react@18.3.1)(react@18.3.1))(react@18.3.1)
|
||||||
react: 18.3.1
|
react: 18.3.1
|
||||||
|
|
||||||
'@chakra-ui/next-js@2.4.2(@chakra-ui/react@2.10.7(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(@types/react@18.3.1)(react@18.3.1))(@types/react@18.3.1)(framer-motion@9.1.7(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(next@14.2.26(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.85.1))(react@18.3.1)':
|
'@chakra-ui/next-js@2.4.2(@chakra-ui/react@2.10.7(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(@types/react@18.3.1)(react@18.3.1))(@types/react@18.3.1)(framer-motion@9.1.7(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(next@14.2.26(@babel/core@7.26.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.85.1))(react@18.3.1)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@chakra-ui/react': 2.10.7(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(@types/react@18.3.1)(react@18.3.1))(@types/react@18.3.1)(framer-motion@9.1.7(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
'@chakra-ui/react': 2.10.7(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(@emotion/styled@11.11.0(@emotion/react@11.11.1(@types/react@18.3.1)(react@18.3.1))(@types/react@18.3.1)(react@18.3.1))(@types/react@18.3.1)(framer-motion@9.1.7(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||||
'@emotion/cache': 11.14.0
|
'@emotion/cache': 11.14.0
|
||||||
@@ -12846,7 +12903,7 @@ snapshots:
|
|||||||
|
|
||||||
'@ungap/structured-clone@1.3.0': {}
|
'@ungap/structured-clone@1.3.0': {}
|
||||||
|
|
||||||
'@vitest/coverage-v8@3.0.8(vitest@3.0.8(@types/debug@4.1.12)(@types/node@20.17.24)(sass@1.85.1)(terser@5.39.0))':
|
'@vitest/coverage-v8@3.1.1(vitest@3.1.1(@types/debug@4.1.12)(@types/node@20.17.24)(sass@1.85.1)(terser@5.39.0))':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@ampproject/remapping': 2.3.0
|
'@ampproject/remapping': 2.3.0
|
||||||
'@bcoe/v8-coverage': 1.0.2
|
'@bcoe/v8-coverage': 1.0.2
|
||||||
@@ -12860,7 +12917,7 @@ snapshots:
|
|||||||
std-env: 3.8.1
|
std-env: 3.8.1
|
||||||
test-exclude: 7.0.1
|
test-exclude: 7.0.1
|
||||||
tinyrainbow: 2.0.0
|
tinyrainbow: 2.0.0
|
||||||
vitest: 3.0.8(@types/debug@4.1.12)(@types/node@20.17.24)(sass@1.85.1)(terser@5.39.0)
|
vitest: 3.1.1(@types/debug@4.1.12)(@types/node@20.17.24)(sass@1.85.1)(terser@5.39.0)
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- supports-color
|
- supports-color
|
||||||
|
|
||||||
@@ -12877,6 +12934,13 @@ snapshots:
|
|||||||
chai: 5.2.0
|
chai: 5.2.0
|
||||||
tinyrainbow: 2.0.0
|
tinyrainbow: 2.0.0
|
||||||
|
|
||||||
|
'@vitest/expect@3.1.1':
|
||||||
|
dependencies:
|
||||||
|
'@vitest/spy': 3.1.1
|
||||||
|
'@vitest/utils': 3.1.1
|
||||||
|
chai: 5.2.0
|
||||||
|
tinyrainbow: 2.0.0
|
||||||
|
|
||||||
'@vitest/mocker@3.0.8(vite@6.2.2(@types/node@20.17.24)(sass@1.85.1)(terser@5.39.0))':
|
'@vitest/mocker@3.0.8(vite@6.2.2(@types/node@20.17.24)(sass@1.85.1)(terser@5.39.0))':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@vitest/spy': 3.0.8
|
'@vitest/spy': 3.0.8
|
||||||
@@ -12885,10 +12949,22 @@ snapshots:
|
|||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
vite: 6.2.2(@types/node@20.17.24)(sass@1.85.1)(terser@5.39.0)
|
vite: 6.2.2(@types/node@20.17.24)(sass@1.85.1)(terser@5.39.0)
|
||||||
|
|
||||||
|
'@vitest/mocker@3.1.1(vite@6.2.2(@types/node@20.17.24)(sass@1.85.1)(terser@5.39.0))':
|
||||||
|
dependencies:
|
||||||
|
'@vitest/spy': 3.1.1
|
||||||
|
estree-walker: 3.0.3
|
||||||
|
magic-string: 0.30.17
|
||||||
|
optionalDependencies:
|
||||||
|
vite: 6.2.2(@types/node@20.17.24)(sass@1.85.1)(terser@5.39.0)
|
||||||
|
|
||||||
'@vitest/pretty-format@3.0.8':
|
'@vitest/pretty-format@3.0.8':
|
||||||
dependencies:
|
dependencies:
|
||||||
tinyrainbow: 2.0.0
|
tinyrainbow: 2.0.0
|
||||||
|
|
||||||
|
'@vitest/pretty-format@3.1.1':
|
||||||
|
dependencies:
|
||||||
|
tinyrainbow: 2.0.0
|
||||||
|
|
||||||
'@vitest/runner@1.6.1':
|
'@vitest/runner@1.6.1':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@vitest/utils': 1.6.1
|
'@vitest/utils': 1.6.1
|
||||||
@@ -12900,6 +12976,11 @@ snapshots:
|
|||||||
'@vitest/utils': 3.0.8
|
'@vitest/utils': 3.0.8
|
||||||
pathe: 2.0.3
|
pathe: 2.0.3
|
||||||
|
|
||||||
|
'@vitest/runner@3.1.1':
|
||||||
|
dependencies:
|
||||||
|
'@vitest/utils': 3.1.1
|
||||||
|
pathe: 2.0.3
|
||||||
|
|
||||||
'@vitest/snapshot@1.6.1':
|
'@vitest/snapshot@1.6.1':
|
||||||
dependencies:
|
dependencies:
|
||||||
magic-string: 0.30.17
|
magic-string: 0.30.17
|
||||||
@@ -12912,6 +12993,12 @@ snapshots:
|
|||||||
magic-string: 0.30.17
|
magic-string: 0.30.17
|
||||||
pathe: 2.0.3
|
pathe: 2.0.3
|
||||||
|
|
||||||
|
'@vitest/snapshot@3.1.1':
|
||||||
|
dependencies:
|
||||||
|
'@vitest/pretty-format': 3.1.1
|
||||||
|
magic-string: 0.30.17
|
||||||
|
pathe: 2.0.3
|
||||||
|
|
||||||
'@vitest/spy@1.6.1':
|
'@vitest/spy@1.6.1':
|
||||||
dependencies:
|
dependencies:
|
||||||
tinyspy: 2.2.1
|
tinyspy: 2.2.1
|
||||||
@@ -12920,6 +13007,10 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
tinyspy: 3.0.2
|
tinyspy: 3.0.2
|
||||||
|
|
||||||
|
'@vitest/spy@3.1.1':
|
||||||
|
dependencies:
|
||||||
|
tinyspy: 3.0.2
|
||||||
|
|
||||||
'@vitest/utils@1.6.1':
|
'@vitest/utils@1.6.1':
|
||||||
dependencies:
|
dependencies:
|
||||||
diff-sequences: 29.6.3
|
diff-sequences: 29.6.3
|
||||||
@@ -12933,6 +13024,12 @@ snapshots:
|
|||||||
loupe: 3.1.3
|
loupe: 3.1.3
|
||||||
tinyrainbow: 2.0.0
|
tinyrainbow: 2.0.0
|
||||||
|
|
||||||
|
'@vitest/utils@3.1.1':
|
||||||
|
dependencies:
|
||||||
|
'@vitest/pretty-format': 3.1.1
|
||||||
|
loupe: 3.1.3
|
||||||
|
tinyrainbow: 2.0.0
|
||||||
|
|
||||||
'@vue/compiler-core@3.5.13':
|
'@vue/compiler-core@3.5.13':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@babel/parser': 7.26.10
|
'@babel/parser': 7.26.10
|
||||||
@@ -16842,7 +16939,7 @@ snapshots:
|
|||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- supports-color
|
- supports-color
|
||||||
|
|
||||||
mdast-util-gfm-autolink-literal@2.0.1(patch_hash=f63d515781110436299ab612306211a9621c6dfaec1ce1a19e2f27454dc70251):
|
mdast-util-gfm-autolink-literal@2.0.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
'@types/mdast': 4.0.4
|
'@types/mdast': 4.0.4
|
||||||
ccount: 2.0.1
|
ccount: 2.0.1
|
||||||
@@ -16890,7 +16987,7 @@ snapshots:
|
|||||||
mdast-util-gfm@3.1.0:
|
mdast-util-gfm@3.1.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
mdast-util-from-markdown: 2.0.2
|
mdast-util-from-markdown: 2.0.2
|
||||||
mdast-util-gfm-autolink-literal: 2.0.1(patch_hash=f63d515781110436299ab612306211a9621c6dfaec1ce1a19e2f27454dc70251)
|
mdast-util-gfm-autolink-literal: 2.0.0
|
||||||
mdast-util-gfm-footnote: 2.1.0
|
mdast-util-gfm-footnote: 2.1.0
|
||||||
mdast-util-gfm-strikethrough: 2.0.0
|
mdast-util-gfm-strikethrough: 2.0.0
|
||||||
mdast-util-gfm-table: 2.0.0
|
mdast-util-gfm-table: 2.0.0
|
||||||
@@ -17647,7 +17744,7 @@ snapshots:
|
|||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- supports-color
|
- supports-color
|
||||||
|
|
||||||
next-i18next@15.4.2(i18next@23.16.8)(next@14.2.26(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.85.1))(react-i18next@14.1.2(i18next@23.16.8)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1):
|
next-i18next@15.4.2(i18next@23.16.8)(next@14.2.26(@babel/core@7.26.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(sass@1.85.1))(react-i18next@14.1.2(i18next@23.16.8)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1):
|
||||||
dependencies:
|
dependencies:
|
||||||
'@babel/runtime': 7.26.10
|
'@babel/runtime': 7.26.10
|
||||||
'@types/hoist-non-react-statics': 3.3.6
|
'@types/hoist-non-react-statics': 3.3.6
|
||||||
@@ -19984,6 +20081,27 @@ snapshots:
|
|||||||
- tsx
|
- tsx
|
||||||
- yaml
|
- yaml
|
||||||
|
|
||||||
|
vite-node@3.1.1(@types/node@20.17.24)(sass@1.85.1)(terser@5.39.0):
|
||||||
|
dependencies:
|
||||||
|
cac: 6.7.14
|
||||||
|
debug: 4.4.0
|
||||||
|
es-module-lexer: 1.6.0
|
||||||
|
pathe: 2.0.3
|
||||||
|
vite: 6.2.2(@types/node@20.17.24)(sass@1.85.1)(terser@5.39.0)
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- '@types/node'
|
||||||
|
- jiti
|
||||||
|
- less
|
||||||
|
- lightningcss
|
||||||
|
- sass
|
||||||
|
- sass-embedded
|
||||||
|
- stylus
|
||||||
|
- sugarss
|
||||||
|
- supports-color
|
||||||
|
- terser
|
||||||
|
- tsx
|
||||||
|
- yaml
|
||||||
|
|
||||||
vite@5.4.14(@types/node@20.17.24)(sass@1.85.1)(terser@5.39.0):
|
vite@5.4.14(@types/node@20.17.24)(sass@1.85.1)(terser@5.39.0):
|
||||||
dependencies:
|
dependencies:
|
||||||
esbuild: 0.21.5
|
esbuild: 0.21.5
|
||||||
@@ -20006,20 +20124,6 @@ snapshots:
|
|||||||
sass: 1.85.1
|
sass: 1.85.1
|
||||||
terser: 5.39.0
|
terser: 5.39.0
|
||||||
|
|
||||||
vitest-mongodb@1.0.1(socks@2.8.4):
|
|
||||||
dependencies:
|
|
||||||
debug: 4.4.0
|
|
||||||
mongodb-memory-server: 10.1.4(socks@2.8.4)
|
|
||||||
transitivePeerDependencies:
|
|
||||||
- '@aws-sdk/credential-providers'
|
|
||||||
- '@mongodb-js/zstd'
|
|
||||||
- gcp-metadata
|
|
||||||
- kerberos
|
|
||||||
- mongodb-client-encryption
|
|
||||||
- snappy
|
|
||||||
- socks
|
|
||||||
- supports-color
|
|
||||||
|
|
||||||
vitest@1.6.1(@types/node@20.17.24)(sass@1.85.1)(terser@5.39.0):
|
vitest@1.6.1(@types/node@20.17.24)(sass@1.85.1)(terser@5.39.0):
|
||||||
dependencies:
|
dependencies:
|
||||||
'@vitest/expect': 1.6.1
|
'@vitest/expect': 1.6.1
|
||||||
@@ -20093,6 +20197,45 @@ snapshots:
|
|||||||
- tsx
|
- tsx
|
||||||
- yaml
|
- yaml
|
||||||
|
|
||||||
|
vitest@3.1.1(@types/debug@4.1.12)(@types/node@20.17.24)(sass@1.85.1)(terser@5.39.0):
|
||||||
|
dependencies:
|
||||||
|
'@vitest/expect': 3.1.1
|
||||||
|
'@vitest/mocker': 3.1.1(vite@6.2.2(@types/node@20.17.24)(sass@1.85.1)(terser@5.39.0))
|
||||||
|
'@vitest/pretty-format': 3.1.1
|
||||||
|
'@vitest/runner': 3.1.1
|
||||||
|
'@vitest/snapshot': 3.1.1
|
||||||
|
'@vitest/spy': 3.1.1
|
||||||
|
'@vitest/utils': 3.1.1
|
||||||
|
chai: 5.2.0
|
||||||
|
debug: 4.4.0
|
||||||
|
expect-type: 1.2.0
|
||||||
|
magic-string: 0.30.17
|
||||||
|
pathe: 2.0.3
|
||||||
|
std-env: 3.8.1
|
||||||
|
tinybench: 2.9.0
|
||||||
|
tinyexec: 0.3.2
|
||||||
|
tinypool: 1.0.2
|
||||||
|
tinyrainbow: 2.0.0
|
||||||
|
vite: 6.2.2(@types/node@20.17.24)(sass@1.85.1)(terser@5.39.0)
|
||||||
|
vite-node: 3.1.1(@types/node@20.17.24)(sass@1.85.1)(terser@5.39.0)
|
||||||
|
why-is-node-running: 2.3.0
|
||||||
|
optionalDependencies:
|
||||||
|
'@types/debug': 4.1.12
|
||||||
|
'@types/node': 20.17.24
|
||||||
|
transitivePeerDependencies:
|
||||||
|
- jiti
|
||||||
|
- less
|
||||||
|
- lightningcss
|
||||||
|
- msw
|
||||||
|
- sass
|
||||||
|
- sass-embedded
|
||||||
|
- stylus
|
||||||
|
- sugarss
|
||||||
|
- supports-color
|
||||||
|
- terser
|
||||||
|
- tsx
|
||||||
|
- yaml
|
||||||
|
|
||||||
void-elements@3.1.0: {}
|
void-elements@3.1.0: {}
|
||||||
|
|
||||||
vue@3.5.13(typescript@5.8.2):
|
vue@3.5.13(typescript@5.8.2):
|
||||||
|
|||||||
@@ -2,6 +2,3 @@ packages:
|
|||||||
- packages/*
|
- packages/*
|
||||||
- projects/*
|
- projects/*
|
||||||
- scripts/icon
|
- scripts/icon
|
||||||
|
|
||||||
patchedDependencies:
|
|
||||||
mdast-util-gfm-autolink-literal@2.0.1: patches/mdast-util-gfm-autolink-literal@2.0.1.patch
|
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import {
|
|||||||
import { ChatBoxInputType, UserInputFileItemType } from './type';
|
import { ChatBoxInputType, UserInputFileItemType } from './type';
|
||||||
import { getFileIcon } from '@fastgpt/global/common/file/icon';
|
import { getFileIcon } from '@fastgpt/global/common/file/icon';
|
||||||
import { ChatItemValueTypeEnum, ChatStatusEnum } from '@fastgpt/global/core/chat/constants';
|
import { ChatItemValueTypeEnum, ChatStatusEnum } from '@fastgpt/global/core/chat/constants';
|
||||||
|
import { extractDeepestInteractive } from '@fastgpt/global/core/workflow/runtime/utils';
|
||||||
|
|
||||||
export const formatChatValue2InputType = (value?: ChatItemValueItemType[]): ChatBoxInputType => {
|
export const formatChatValue2InputType = (value?: ChatItemValueItemType[]): ChatBoxInputType => {
|
||||||
if (!value) {
|
if (!value) {
|
||||||
@@ -82,17 +83,19 @@ export const setUserSelectResultToHistories = (
|
|||||||
i !== item.value.length - 1 ||
|
i !== item.value.length - 1 ||
|
||||||
val.type !== ChatItemValueTypeEnum.interactive ||
|
val.type !== ChatItemValueTypeEnum.interactive ||
|
||||||
!val.interactive
|
!val.interactive
|
||||||
)
|
) {
|
||||||
return val;
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
if (val.interactive.type === 'userSelect') {
|
const finalInteractive = extractDeepestInteractive(val.interactive);
|
||||||
|
if (finalInteractive.type === 'userSelect') {
|
||||||
return {
|
return {
|
||||||
...val,
|
...val,
|
||||||
interactive: {
|
interactive: {
|
||||||
...val.interactive,
|
...finalInteractive,
|
||||||
params: {
|
params: {
|
||||||
...val.interactive.params,
|
...finalInteractive.params,
|
||||||
userSelectedVal: val.interactive.params.userSelectOptions.find(
|
userSelectedVal: finalInteractive.params.userSelectOptions.find(
|
||||||
(item) => item.value === interactiveVal
|
(item) => item.value === interactiveVal
|
||||||
)?.value
|
)?.value
|
||||||
}
|
}
|
||||||
@@ -100,13 +103,13 @@ export const setUserSelectResultToHistories = (
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (val.interactive.type === 'userInput') {
|
if (finalInteractive.type === 'userInput') {
|
||||||
return {
|
return {
|
||||||
...val,
|
...val,
|
||||||
interactive: {
|
interactive: {
|
||||||
...val.interactive,
|
...finalInteractive,
|
||||||
params: {
|
params: {
|
||||||
...val.interactive.params,
|
...finalInteractive.params,
|
||||||
submitted: true
|
submitted: true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ import { isEqual } from 'lodash';
|
|||||||
import { useTranslation } from 'next-i18next';
|
import { useTranslation } from 'next-i18next';
|
||||||
import { eventBus, EventNameEnum } from '@/web/common/utils/eventbus';
|
import { eventBus, EventNameEnum } from '@/web/common/utils/eventbus';
|
||||||
import { SelectOptionsComponent, FormInputComponent } from './Interactive/InteractiveComponents';
|
import { SelectOptionsComponent, FormInputComponent } from './Interactive/InteractiveComponents';
|
||||||
|
import { extractDeepestInteractive } from '@fastgpt/global/core/workflow/runtime/utils';
|
||||||
|
|
||||||
const accordionButtonStyle = {
|
const accordionButtonStyle = {
|
||||||
w: 'auto',
|
w: 'auto',
|
||||||
@@ -245,11 +246,12 @@ const AIResponseBox = ({
|
|||||||
return <RenderTool showAnimation={isChatting} tools={value.tools} />;
|
return <RenderTool showAnimation={isChatting} tools={value.tools} />;
|
||||||
}
|
}
|
||||||
if (value.type === ChatItemValueTypeEnum.interactive && value.interactive) {
|
if (value.type === ChatItemValueTypeEnum.interactive && value.interactive) {
|
||||||
if (value.interactive.type === 'userSelect') {
|
const finalInteractive = extractDeepestInteractive(value.interactive);
|
||||||
return <RenderUserSelectInteractive interactive={value.interactive} />;
|
if (finalInteractive.type === 'userSelect') {
|
||||||
|
return <RenderUserSelectInteractive interactive={finalInteractive} />;
|
||||||
}
|
}
|
||||||
if (value.interactive?.type === 'userInput') {
|
if (finalInteractive.type === 'userInput') {
|
||||||
return <RenderUserFormInteractive interactive={value.interactive} />;
|
return <RenderUserFormInteractive interactive={finalInteractive} />;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
@@ -1,20 +1,24 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
import { useTranslation } from 'next-i18next';
|
||||||
import { Box, Checkbox, HStack, VStack } from '@chakra-ui/react';
|
import { Box, Checkbox, HStack, VStack } from '@chakra-ui/react';
|
||||||
import Avatar from '@fastgpt/web/components/common/Avatar';
|
import Avatar from '@fastgpt/web/components/common/Avatar';
|
||||||
import PermissionTags from './PermissionTags';
|
import PermissionTags from './PermissionTags';
|
||||||
import { PermissionValueType } from '@fastgpt/global/support/permission/type';
|
import { PermissionValueType } from '@fastgpt/global/support/permission/type';
|
||||||
import MyIcon from '@fastgpt/web/components/common/Icon';
|
import MyIcon from '@fastgpt/web/components/common/Icon';
|
||||||
import OrgTags from '../../user/team/OrgTags';
|
import OrgTags from '../../user/team/OrgTags';
|
||||||
|
import Tag from '@fastgpt/web/components/common/Tag';
|
||||||
|
|
||||||
function MemberItemCard({
|
function MemberItemCard({
|
||||||
avatar,
|
avatar,
|
||||||
key,
|
key,
|
||||||
onChange,
|
onChange: _onChange,
|
||||||
isChecked,
|
isChecked,
|
||||||
onDelete,
|
onDelete,
|
||||||
name,
|
name,
|
||||||
permission,
|
permission,
|
||||||
orgs
|
orgs,
|
||||||
|
addOnly,
|
||||||
|
rightSlot
|
||||||
}: {
|
}: {
|
||||||
avatar: string;
|
avatar: string;
|
||||||
key: string;
|
key: string;
|
||||||
@@ -23,44 +27,66 @@ function MemberItemCard({
|
|||||||
onDelete?: () => void;
|
onDelete?: () => void;
|
||||||
name: string;
|
name: string;
|
||||||
permission?: PermissionValueType;
|
permission?: PermissionValueType;
|
||||||
|
addOnly?: boolean;
|
||||||
orgs?: string[];
|
orgs?: string[];
|
||||||
|
rightSlot?: React.ReactNode;
|
||||||
}) {
|
}) {
|
||||||
|
const isAdded = addOnly && !!permission;
|
||||||
|
const onChange = () => {
|
||||||
|
if (!isAdded) _onChange();
|
||||||
|
};
|
||||||
|
const { t } = useTranslation();
|
||||||
return (
|
return (
|
||||||
<>
|
<HStack
|
||||||
<HStack
|
justifyContent="space-between"
|
||||||
justifyContent="space-between"
|
alignItems="center"
|
||||||
alignItems="center"
|
key={key}
|
||||||
key={key}
|
px="3"
|
||||||
px="3"
|
py="2"
|
||||||
py="2"
|
borderRadius="sm"
|
||||||
borderRadius="sm"
|
_hover={{
|
||||||
_hover={{
|
bgColor: 'myGray.50',
|
||||||
bgColor: 'myGray.50',
|
cursor: 'pointer'
|
||||||
cursor: 'pointer'
|
}}
|
||||||
}}
|
onClick={onChange}
|
||||||
onClick={onChange}
|
>
|
||||||
>
|
{isChecked !== undefined && (
|
||||||
{isChecked !== undefined && <Checkbox isChecked={isChecked} pointerEvents="none" />}
|
<Checkbox isChecked={isChecked} pointerEvents="none" disabled={isAdded} />
|
||||||
<Avatar src={avatar} w="1.5rem" borderRadius={'50%'} />
|
)}
|
||||||
|
<Avatar src={avatar} w="1.5rem" borderRadius={'50%'} />
|
||||||
|
|
||||||
<Box w="full">
|
<Box w="full">
|
||||||
<Box fontSize={'sm'}>{name}</Box>
|
<Box fontSize={'sm'} className="textEllipsis" maxW="300px">
|
||||||
<Box lineHeight={1}>{orgs && orgs.length > 0 && <OrgTags orgs={orgs} />}</Box>
|
{name}
|
||||||
</Box>
|
</Box>
|
||||||
{permission && <PermissionTags permission={permission} />}
|
<Box lineHeight={1}>{orgs && orgs.length > 0 && <OrgTags orgs={orgs} />}</Box>
|
||||||
{onDelete !== undefined && (
|
</Box>
|
||||||
<MyIcon
|
{!isAdded && permission && <PermissionTags permission={permission} />}
|
||||||
name="common/closeLight"
|
{isAdded && (
|
||||||
w="1rem"
|
<Tag
|
||||||
cursor={'pointer'}
|
mixBlendMode={'multiply'}
|
||||||
_hover={{
|
colorSchema="blue"
|
||||||
color: 'red.600'
|
border="none"
|
||||||
}}
|
py={2}
|
||||||
onClick={onDelete}
|
px={3}
|
||||||
/>
|
fontSize={'xs'}
|
||||||
)}
|
>
|
||||||
</HStack>
|
{t('user:team.collaborator.added')}
|
||||||
</>
|
</Tag>
|
||||||
|
)}
|
||||||
|
{onDelete !== undefined && (
|
||||||
|
<MyIcon
|
||||||
|
name="common/closeLight"
|
||||||
|
w="1rem"
|
||||||
|
cursor={'pointer'}
|
||||||
|
_hover={{
|
||||||
|
color: 'red.600'
|
||||||
|
}}
|
||||||
|
onClick={onDelete}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
{rightSlot}
|
||||||
|
</HStack>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,17 +1,6 @@
|
|||||||
import { useUserStore } from '@/web/support/user/useUserStore';
|
import { useUserStore } from '@/web/support/user/useUserStore';
|
||||||
import { ChevronDownIcon } from '@chakra-ui/icons';
|
import { ChevronDownIcon } from '@chakra-ui/icons';
|
||||||
import {
|
import { Box, Button, Flex, Grid, HStack, ModalBody, ModalFooter, Text } from '@chakra-ui/react';
|
||||||
Box,
|
|
||||||
Button,
|
|
||||||
Checkbox,
|
|
||||||
Flex,
|
|
||||||
Grid,
|
|
||||||
HStack,
|
|
||||||
ModalBody,
|
|
||||||
ModalFooter,
|
|
||||||
Tag,
|
|
||||||
Text
|
|
||||||
} from '@chakra-ui/react';
|
|
||||||
import { DefaultGroupName } from '@fastgpt/global/support/user/team/group/constant';
|
import { DefaultGroupName } from '@fastgpt/global/support/user/team/group/constant';
|
||||||
import MyAvatar from '@fastgpt/web/components/common/Avatar';
|
import MyAvatar from '@fastgpt/web/components/common/Avatar';
|
||||||
import MyIcon from '@fastgpt/web/components/common/Icon';
|
import MyIcon from '@fastgpt/web/components/common/Icon';
|
||||||
@@ -19,27 +8,26 @@ import SearchInput from '@fastgpt/web/components/common/Input/SearchInput';
|
|||||||
import MyModal from '@fastgpt/web/components/common/MyModal';
|
import MyModal from '@fastgpt/web/components/common/MyModal';
|
||||||
import { useRequest2 } from '@fastgpt/web/hooks/useRequest';
|
import { useRequest2 } from '@fastgpt/web/hooks/useRequest';
|
||||||
import { useTranslation } from 'next-i18next';
|
import { useTranslation } from 'next-i18next';
|
||||||
import { useEffect, useMemo, useRef, useState } from 'react';
|
import { useMemo, useRef, useState } from 'react';
|
||||||
import PermissionSelect from './PermissionSelect';
|
import PermissionSelect from './PermissionSelect';
|
||||||
import PermissionTags from './PermissionTags';
|
|
||||||
import {
|
import {
|
||||||
DEFAULT_ORG_AVATAR,
|
DEFAULT_ORG_AVATAR,
|
||||||
DEFAULT_TEAM_AVATAR,
|
DEFAULT_TEAM_AVATAR,
|
||||||
DEFAULT_USER_AVATAR
|
DEFAULT_USER_AVATAR
|
||||||
} from '@fastgpt/global/common/system/constants';
|
} from '@fastgpt/global/common/system/constants';
|
||||||
import Path from '@/components/common/folder/Path';
|
import Path from '@/components/common/folder/Path';
|
||||||
import { OrgListItemType, OrgType } from '@fastgpt/global/support/user/team/org/type';
|
import { OrgListItemType } from '@fastgpt/global/support/user/team/org/type';
|
||||||
import { useContextSelector } from 'use-context-selector';
|
import { useContextSelector } from 'use-context-selector';
|
||||||
import { CollaboratorContext } from './context';
|
import { CollaboratorContext } from './context';
|
||||||
import { getTeamMembers } from '@/web/support/user/team/api';
|
import { getTeamMembers } from '@/web/support/user/team/api';
|
||||||
import { getGroupList } from '@/web/support/user/team/group/api';
|
import { getGroupList } from '@/web/support/user/team/group/api';
|
||||||
import { useScrollPagination } from '@fastgpt/web/hooks/useScrollPagination';
|
import { useScrollPagination } from '@fastgpt/web/hooks/useScrollPagination';
|
||||||
import MemberItemCard from './MemberItemCard';
|
import MemberItemCard from './MemberItemCard';
|
||||||
import { GetSearchUserGroupOrg } from '@/web/support/user/api';
|
|
||||||
import useOrg from '@/web/support/user/team/org/hooks/useOrg';
|
import useOrg from '@/web/support/user/team/org/hooks/useOrg';
|
||||||
import { TeamMemberItemType } from '@fastgpt/global/support/user/team/type';
|
import { TeamMemberItemType } from '@fastgpt/global/support/user/team/type';
|
||||||
import { MemberGroupListItemType } from '@fastgpt/global/support/permission/memberGroup/type';
|
import { MemberGroupListItemType } from '@fastgpt/global/support/permission/memberGroup/type';
|
||||||
import _ from 'lodash';
|
import { UpdateClbPermissionProps } from '@fastgpt/global/support/permission/collaborator';
|
||||||
|
import { ValueOf } from 'next/dist/shared/lib/constants';
|
||||||
|
|
||||||
const HoverBoxStyle = {
|
const HoverBoxStyle = {
|
||||||
bgColor: 'myGray.50',
|
bgColor: 'myGray.50',
|
||||||
@@ -131,8 +119,8 @@ function MemberModal({
|
|||||||
members: selectedMemberList.map((item) => item.tmbId),
|
members: selectedMemberList.map((item) => item.tmbId),
|
||||||
groups: selectedGroupList.map((item) => item._id),
|
groups: selectedGroupList.map((item) => item._id),
|
||||||
orgs: selectedOrgList.map((item) => item._id),
|
orgs: selectedOrgList.map((item) => item._id),
|
||||||
permission: selectedPermission!
|
permission: addOnly ? undefined : selectedPermission!
|
||||||
}),
|
} as UpdateClbPermissionProps<ValueOf<typeof addOnly>>),
|
||||||
{
|
{
|
||||||
successToast: t('common:common.Add Success'),
|
successToast: t('common:common.Add Success'),
|
||||||
onSuccess() {
|
onSuccess() {
|
||||||
@@ -285,6 +273,7 @@ function MemberModal({
|
|||||||
const collaborator = collaboratorList?.find((v) => v.tmbId === member.tmbId);
|
const collaborator = collaboratorList?.find((v) => v.tmbId === member.tmbId);
|
||||||
return (
|
return (
|
||||||
<MemberItemCard
|
<MemberItemCard
|
||||||
|
addOnly={addOnly}
|
||||||
avatar={member.avatar}
|
avatar={member.avatar}
|
||||||
key={member.tmbId}
|
key={member.tmbId}
|
||||||
name={member.memberName}
|
name={member.memberName}
|
||||||
@@ -321,49 +310,33 @@ function MemberModal({
|
|||||||
};
|
};
|
||||||
const collaborator = collaboratorList?.find((v) => v.orgId === org._id);
|
const collaborator = collaboratorList?.find((v) => v.orgId === org._id);
|
||||||
return (
|
return (
|
||||||
<HStack
|
<MemberItemCard
|
||||||
justifyContent="space-between"
|
avatar={org.avatar}
|
||||||
key={org._id}
|
key={org._id}
|
||||||
py="2"
|
name={org.name}
|
||||||
px="3"
|
onChange={onChange}
|
||||||
borderRadius="sm"
|
addOnly={addOnly}
|
||||||
alignItems="center"
|
permission={collaborator?.permission.value}
|
||||||
_hover={HoverBoxStyle}
|
isChecked={!!selectedOrgList.find((v) => String(v._id) === String(org._id))}
|
||||||
onClick={onChange}
|
rightSlot={
|
||||||
>
|
org.total && (
|
||||||
<Checkbox
|
<MyIcon
|
||||||
isChecked={!!selectedOrgList.find((v) => v._id === org._id)}
|
name="core/chat/chevronRight"
|
||||||
pointerEvents="none"
|
w="16px"
|
||||||
/>
|
p="4px"
|
||||||
<MyAvatar src={org.avatar} w="1.5rem" borderRadius={'50%'} />
|
rounded={'6px'}
|
||||||
<HStack w="full">
|
_hover={{
|
||||||
<Text>{org.name}</Text>
|
bgColor: 'myGray.200'
|
||||||
{org.total && (
|
}}
|
||||||
<>
|
onClick={(e) => {
|
||||||
<Tag size="sm" my="auto">
|
onClickOrg(org);
|
||||||
{org.total}
|
// setPath(getOrgChildrenPath(org));
|
||||||
</Tag>
|
e.stopPropagation();
|
||||||
</>
|
}}
|
||||||
)}
|
/>
|
||||||
</HStack>
|
)
|
||||||
<PermissionTags permission={collaborator?.permission.value} />
|
}
|
||||||
{org.total && (
|
/>
|
||||||
<MyIcon
|
|
||||||
name="core/chat/chevronRight"
|
|
||||||
w="16px"
|
|
||||||
p="4px"
|
|
||||||
rounded={'6px'}
|
|
||||||
_hover={{
|
|
||||||
bgColor: 'myGray.200'
|
|
||||||
}}
|
|
||||||
onClick={(e) => {
|
|
||||||
onClickOrg(org);
|
|
||||||
// setPath(getOrgChildrenPath(org));
|
|
||||||
e.stopPropagation();
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</HStack>
|
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
return searchKey ? (
|
return searchKey ? (
|
||||||
@@ -372,6 +345,9 @@ function MemberModal({
|
|||||||
<OrgMemberScrollData>
|
<OrgMemberScrollData>
|
||||||
{Orgs}
|
{Orgs}
|
||||||
{orgMembers.map((member) => {
|
{orgMembers.map((member) => {
|
||||||
|
const isChecked = !!selectedMemberList.find(
|
||||||
|
(v) => v.tmbId === member.tmbId
|
||||||
|
);
|
||||||
return (
|
return (
|
||||||
<MemberItemCard
|
<MemberItemCard
|
||||||
avatar={member.avatar}
|
avatar={member.avatar}
|
||||||
@@ -385,7 +361,9 @@ function MemberModal({
|
|||||||
return [...state, member];
|
return [...state, member];
|
||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
isChecked={!!selectedMemberList.find((v) => v.tmbId === member.tmbId)}
|
isChecked={isChecked}
|
||||||
|
permission={member.permission.value}
|
||||||
|
addOnly={addOnly && !!member.permission.value}
|
||||||
orgs={member.orgs}
|
orgs={member.orgs}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
@@ -414,6 +392,7 @@ function MemberModal({
|
|||||||
permission={collaborator?.permission.value}
|
permission={collaborator?.permission.value}
|
||||||
onChange={onChange}
|
onChange={onChange}
|
||||||
isChecked={!!selectedGroupList.find((v) => v._id === group._id)}
|
isChecked={!!selectedGroupList.find((v) => v._id === group._id)}
|
||||||
|
addOnly={addOnly}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
|
|||||||
@@ -110,7 +110,15 @@ const CollaboratorContextProvider = ({
|
|||||||
} = useRequest2(
|
} = useRequest2(
|
||||||
async () => {
|
async () => {
|
||||||
if (feConfigs.isPlus) {
|
if (feConfigs.isPlus) {
|
||||||
return onGetCollaboratorList();
|
const data = await onGetCollaboratorList();
|
||||||
|
return data.map((item) => {
|
||||||
|
return {
|
||||||
|
...item,
|
||||||
|
permission: new Permission({
|
||||||
|
per: item.permission.value
|
||||||
|
})
|
||||||
|
};
|
||||||
|
});
|
||||||
}
|
}
|
||||||
return [];
|
return [];
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -10,7 +10,14 @@ function OrgTags({ orgs, type = 'simple' }: { orgs?: string[]; type?: 'simple' |
|
|||||||
label={
|
label={
|
||||||
<VStack gap="1" alignItems={'start'}>
|
<VStack gap="1" alignItems={'start'}>
|
||||||
{orgs.map((org, index) => (
|
{orgs.map((org, index) => (
|
||||||
<Box key={index} fontSize="sm" fontWeight={400} color="myGray.500">
|
<Box
|
||||||
|
key={index}
|
||||||
|
fontSize="sm"
|
||||||
|
fontWeight={400}
|
||||||
|
color="myGray.500"
|
||||||
|
maxW={'300px'}
|
||||||
|
className="textEllipsis"
|
||||||
|
>
|
||||||
{org.slice(1)}
|
{org.slice(1)}
|
||||||
</Box>
|
</Box>
|
||||||
))}
|
))}
|
||||||
|
|||||||
@@ -91,7 +91,7 @@ const AccountContainer = ({
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
: []),
|
: []),
|
||||||
...(userInfo?.team?.permission.hasManagePer
|
...(userInfo?.team?.permission.hasApikeyCreatePer
|
||||||
? [
|
? [
|
||||||
{
|
{
|
||||||
icon: 'key',
|
icon: 'key',
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import { useTranslation } from 'next-i18next';
|
|||||||
import { useForm } from 'react-hook-form';
|
import { useForm } from 'react-hook-form';
|
||||||
import { useRequest2 } from '@fastgpt/web/hooks/useRequest';
|
import { useRequest2 } from '@fastgpt/web/hooks/useRequest';
|
||||||
import { updatePasswordByOld } from '@/web/support/user/api';
|
import { updatePasswordByOld } from '@/web/support/user/api';
|
||||||
import { PasswordRule } from '@/web/support/user/login/constants';
|
import { checkPasswordRule } from '@/web/support/user/login/constants';
|
||||||
import { useToast } from '@fastgpt/web/hooks/useToast';
|
import { useToast } from '@fastgpt/web/hooks/useToast';
|
||||||
|
|
||||||
type FormType = {
|
type FormType = {
|
||||||
@@ -70,9 +70,11 @@ const UpdatePswModal = ({ onClose }: { onClose: () => void }) => {
|
|||||||
placeholder={t('account_info:password_tip')}
|
placeholder={t('account_info:password_tip')}
|
||||||
{...register('newPsw', {
|
{...register('newPsw', {
|
||||||
required: true,
|
required: true,
|
||||||
pattern: {
|
validate: (val) => {
|
||||||
value: PasswordRule,
|
if (!checkPasswordRule(val)) {
|
||||||
message: t('account_info:password_tip')
|
return t('login:password_tip');
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
})}
|
})}
|
||||||
></Input>
|
></Input>
|
||||||
|
|||||||
@@ -303,7 +303,7 @@ function MemberTable({ Tabs }: { Tabs: React.ReactNode }) {
|
|||||||
})()}
|
})()}
|
||||||
</Td>
|
</Td>
|
||||||
<Td maxW={'300px'}>
|
<Td maxW={'300px'}>
|
||||||
<VStack gap={0}>
|
<VStack gap={0} align="start">
|
||||||
<Box>{format(new Date(member.createTime), 'yyyy-MM-dd HH:mm:ss')}</Box>
|
<Box>{format(new Date(member.createTime), 'yyyy-MM-dd HH:mm:ss')}</Box>
|
||||||
<Box>
|
<Box>
|
||||||
{member.updateTime
|
{member.updateTime
|
||||||
|
|||||||
@@ -0,0 +1,102 @@
|
|||||||
|
import {
|
||||||
|
Box,
|
||||||
|
Button,
|
||||||
|
Flex,
|
||||||
|
Table,
|
||||||
|
TableContainer,
|
||||||
|
Tbody,
|
||||||
|
Td,
|
||||||
|
Th,
|
||||||
|
Thead,
|
||||||
|
Tr
|
||||||
|
} from '@chakra-ui/react';
|
||||||
|
import { useState } from 'react';
|
||||||
|
import { useTranslation } from 'next-i18next';
|
||||||
|
import MyBox from '@fastgpt/web/components/common/MyBox';
|
||||||
|
import SearchInput from '@fastgpt/web/components/common/Input/SearchInput';
|
||||||
|
import { useScrollPagination } from '@fastgpt/web/hooks/useScrollPagination';
|
||||||
|
import { getOperationLogs } from '@/web/support/user/team/operantionLog/api';
|
||||||
|
import { TeamPermission } from '@fastgpt/global/support/permission/user/controller';
|
||||||
|
import { operationLogI18nMap } from '@fastgpt/service/support/operationLog/constants';
|
||||||
|
import { OperationLogEventEnum } from '@fastgpt/global/support/operationLog/constants';
|
||||||
|
import { formatTime2YMDHMS } from '@fastgpt/global/common/string/time';
|
||||||
|
import UserBox from '@fastgpt/web/components/common/UserBox';
|
||||||
|
|
||||||
|
function OperationLogTable({ Tabs }: { Tabs: React.ReactNode }) {
|
||||||
|
const { t } = useTranslation();
|
||||||
|
|
||||||
|
const [searchKey, setSearchKey] = useState<string>('');
|
||||||
|
const {
|
||||||
|
data: operationLogs = [],
|
||||||
|
isLoading: loadingLogs,
|
||||||
|
ScrollData: LogScrollData
|
||||||
|
} = useScrollPagination(getOperationLogs, {
|
||||||
|
pageSize: 20,
|
||||||
|
refreshDeps: [searchKey],
|
||||||
|
throttleWait: 500,
|
||||||
|
debounceWait: 200
|
||||||
|
});
|
||||||
|
|
||||||
|
const isLoading = loadingLogs;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Flex justify={'space-between'} align={'center'} pb={'1rem'}>
|
||||||
|
{Tabs}
|
||||||
|
</Flex>
|
||||||
|
|
||||||
|
<MyBox isLoading={isLoading} flex={'1 0 0'} overflow={'auto'}>
|
||||||
|
<LogScrollData>
|
||||||
|
<TableContainer overflow={'unset'} fontSize={'sm'}>
|
||||||
|
<Table overflow={'unset'}>
|
||||||
|
<Thead>
|
||||||
|
<Tr bgColor={'white !important'}>
|
||||||
|
<Th borderLeftRadius="6px" bgColor="myGray.100">
|
||||||
|
{t('account_team:log_user')}
|
||||||
|
</Th>
|
||||||
|
<Th bgColor="myGray.100">{t('account_team:log_time')}</Th>
|
||||||
|
<Th bgColor="myGray.100">{t('account_team:log_type')}</Th>
|
||||||
|
<Th bgColor="myGray.100">{t('account_team:log_details')}</Th>
|
||||||
|
</Tr>
|
||||||
|
</Thead>
|
||||||
|
<Tbody>
|
||||||
|
{operationLogs?.map((log) => {
|
||||||
|
const i18nData = operationLogI18nMap[log.event];
|
||||||
|
const metadata = { ...log.metadata };
|
||||||
|
|
||||||
|
if (log.event === OperationLogEventEnum.ASSIGN_PERMISSION) {
|
||||||
|
const permissionValue = parseInt(metadata.permission, 10);
|
||||||
|
|
||||||
|
const permission = new TeamPermission({ per: permissionValue });
|
||||||
|
metadata.appCreate = permission.hasAppCreatePer ? '✔' : '✘';
|
||||||
|
metadata.datasetCreate = permission.hasDatasetCreatePer ? '✔' : '✘';
|
||||||
|
metadata.apiKeyCreate = permission.hasApikeyCreatePer ? '✔' : '✘';
|
||||||
|
metadata.manage = permission.hasManagePer ? '✔' : '✘';
|
||||||
|
}
|
||||||
|
|
||||||
|
return i18nData ? (
|
||||||
|
<Tr key={log._id} overflow={'unset'}>
|
||||||
|
<Td>
|
||||||
|
<UserBox
|
||||||
|
sourceMember={log.sourceMember}
|
||||||
|
fontSize="sm"
|
||||||
|
avatarSize="1rem"
|
||||||
|
spacing={0.5}
|
||||||
|
/>
|
||||||
|
</Td>
|
||||||
|
<Td>{formatTime2YMDHMS(log.timestamp)}</Td>
|
||||||
|
<Td>{t(i18nData.typeLabel)}</Td>
|
||||||
|
<Td>{t(i18nData.content, metadata as any) as string}</Td>
|
||||||
|
</Tr>
|
||||||
|
) : null;
|
||||||
|
})}
|
||||||
|
</Tbody>
|
||||||
|
</Table>
|
||||||
|
</TableContainer>
|
||||||
|
</LogScrollData>
|
||||||
|
</MyBox>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default OperationLogTable;
|
||||||
@@ -27,6 +27,9 @@ import Avatar from '@fastgpt/web/components/common/Avatar';
|
|||||||
import MemberTag from '../../../../components/support/user/team/Info/MemberTag';
|
import MemberTag from '../../../../components/support/user/team/Info/MemberTag';
|
||||||
import { DefaultGroupName } from '@fastgpt/global/support/user/team/group/constant';
|
import { DefaultGroupName } from '@fastgpt/global/support/user/team/group/constant';
|
||||||
import {
|
import {
|
||||||
|
TeamApikeyCreatePermissionVal,
|
||||||
|
TeamAppCreatePermissionVal,
|
||||||
|
TeamDatasetCreatePermissionVal,
|
||||||
TeamManagePermissionVal,
|
TeamManagePermissionVal,
|
||||||
TeamPermissionList,
|
TeamPermissionList,
|
||||||
TeamWritePermissionVal
|
TeamWritePermissionVal
|
||||||
@@ -42,6 +45,9 @@ import MyIcon from '@fastgpt/web/components/common/Icon';
|
|||||||
import { useContextSelector } from 'use-context-selector';
|
import { useContextSelector } from 'use-context-selector';
|
||||||
import SearchInput from '@fastgpt/web/components/common/Input/SearchInput';
|
import SearchInput from '@fastgpt/web/components/common/Input/SearchInput';
|
||||||
import { GetSearchUserGroupOrg } from '@/web/support/user/api';
|
import { GetSearchUserGroupOrg } from '@/web/support/user/api';
|
||||||
|
import { PermissionValueType } from '@fastgpt/global/support/permission/type';
|
||||||
|
import { CollaboratorItemType } from '@fastgpt/global/support/permission/collaborator';
|
||||||
|
import { Permission } from '@fastgpt/global/support/permission/controller';
|
||||||
|
|
||||||
function PermissionManage({
|
function PermissionManage({
|
||||||
Tabs,
|
Tabs,
|
||||||
@@ -104,19 +110,18 @@ function PermissionManage({
|
|||||||
}, [collaboratorList, searchResult, searchKey]);
|
}, [collaboratorList, searchResult, searchKey]);
|
||||||
|
|
||||||
const { runAsync: onUpdatePermission, loading: addLoading } = useRequest2(
|
const { runAsync: onUpdatePermission, loading: addLoading } = useRequest2(
|
||||||
async ({ id, type, per }: { id: string; type: 'add' | 'remove'; per: 'write' | 'manage' }) => {
|
async ({ id, type, per }: { id: string; type: 'add' | 'remove'; per: PermissionValueType }) => {
|
||||||
const clb = collaboratorList.find(
|
const clb = collaboratorList.find(
|
||||||
(clb) => clb.tmbId === id || clb.groupId === id || clb.orgId === id
|
(clb) => clb.tmbId === id || clb.groupId === id || clb.orgId === id
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!clb) return;
|
if (!clb) return;
|
||||||
|
|
||||||
const updatePer = per === 'write' ? TeamWritePermissionVal : TeamManagePermissionVal;
|
|
||||||
const permission = new TeamPermission({ per: clb.permission.value });
|
const permission = new TeamPermission({ per: clb.permission.value });
|
||||||
if (type === 'add') {
|
if (type === 'add') {
|
||||||
permission.addPer(updatePer);
|
permission.addPer(per);
|
||||||
} else {
|
} else {
|
||||||
permission.removePer(updatePer);
|
permission.removePer(per);
|
||||||
}
|
}
|
||||||
|
|
||||||
return onUpdateCollaborators({
|
return onUpdateCollaborators({
|
||||||
@@ -132,12 +137,48 @@ function PermissionManage({
|
|||||||
useRequest2(onDelOneCollaborator);
|
useRequest2(onDelOneCollaborator);
|
||||||
|
|
||||||
const userManage = userInfo?.permission.hasManagePer;
|
const userManage = userInfo?.permission.hasManagePer;
|
||||||
const hasDeletePer = (per: TeamPermission) => {
|
const hasDeletePer = (per: Permission) => {
|
||||||
if (userInfo?.permission.isOwner) return true;
|
if (userInfo?.permission.isOwner) return true;
|
||||||
if (userManage && !per.hasManagePer) return true;
|
if (userManage && !per.hasManagePer) return true;
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function PermissionCheckBox({
|
||||||
|
isDisabled,
|
||||||
|
per,
|
||||||
|
clbPer,
|
||||||
|
id
|
||||||
|
}: {
|
||||||
|
isDisabled: boolean;
|
||||||
|
per: PermissionValueType;
|
||||||
|
clbPer: Permission;
|
||||||
|
id: string;
|
||||||
|
}) {
|
||||||
|
return (
|
||||||
|
<Td>
|
||||||
|
<Box mx="auto" w="fit-content">
|
||||||
|
<Checkbox
|
||||||
|
isDisabled={isDisabled}
|
||||||
|
isChecked={clbPer.checkPer(per)}
|
||||||
|
onChange={(e) =>
|
||||||
|
e.target.checked
|
||||||
|
? onUpdatePermission({
|
||||||
|
id,
|
||||||
|
type: 'add',
|
||||||
|
per
|
||||||
|
})
|
||||||
|
: onUpdatePermission({
|
||||||
|
id,
|
||||||
|
type: 'remove',
|
||||||
|
per
|
||||||
|
})
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
|
</Td>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Flex justify={'space-between'} align={'center'} pb={'1rem'}>
|
<Flex justify={'space-between'} align={'center'} pb={'1rem'}>
|
||||||
@@ -174,13 +215,26 @@ function PermissionManage({
|
|||||||
</Th>
|
</Th>
|
||||||
<Th bg="myGray.100">
|
<Th bg="myGray.100">
|
||||||
<Box mx="auto" w="fit-content">
|
<Box mx="auto" w="fit-content">
|
||||||
{t('user:team.group.permission.write')}
|
{t('account_team:permission_appCreate')}
|
||||||
|
<QuestionTip ml="1" label={t('account_team:permission_appCreate_tip')} />
|
||||||
</Box>
|
</Box>
|
||||||
</Th>
|
</Th>
|
||||||
<Th bg="myGray.100">
|
<Th bg="myGray.100">
|
||||||
<Box mx="auto" w="fit-content">
|
<Box mx="auto" w="fit-content">
|
||||||
{t('user:team.group.permission.manage')}
|
{t('account_team:permission_datasetCreate')}
|
||||||
<QuestionTip ml="1" label={t('user:team.group.manage_tip')} />
|
<QuestionTip ml="1" label={t('account_team:permission_datasetCreate_Tip')} />
|
||||||
|
</Box>
|
||||||
|
</Th>
|
||||||
|
<Th bg="myGray.100">
|
||||||
|
<Box mx="auto" w="fit-content">
|
||||||
|
{t('account_team:permission_apikeyCreate')}
|
||||||
|
<QuestionTip ml="1" label={t('account_team:permission_apikeyCreate_Tip')} />
|
||||||
|
</Box>
|
||||||
|
</Th>
|
||||||
|
<Th bg="myGray.100">
|
||||||
|
<Box mx="auto" w="fit-content">
|
||||||
|
{t('account_team:permission_manage')}
|
||||||
|
<QuestionTip ml="1" label={t('account_team:permission_manage_tip')} />
|
||||||
</Box>
|
</Box>
|
||||||
</Th>
|
</Th>
|
||||||
<Th bg="myGray.100" borderRightRadius="md">
|
<Th bg="myGray.100" borderRightRadius="md">
|
||||||
@@ -210,48 +264,30 @@ function PermissionManage({
|
|||||||
<Box>{member.name}</Box>
|
<Box>{member.name}</Box>
|
||||||
</HStack>
|
</HStack>
|
||||||
</Td>
|
</Td>
|
||||||
<Td>
|
<PermissionCheckBox
|
||||||
<Box mx="auto" w="fit-content">
|
isDisabled={member.permission.isOwner || !userManage}
|
||||||
<Checkbox
|
per={TeamAppCreatePermissionVal}
|
||||||
isDisabled={member.permission.isOwner || !userManage}
|
clbPer={member.permission}
|
||||||
isChecked={member.permission.hasWritePer}
|
id={member.tmbId!}
|
||||||
onChange={(e) =>
|
/>
|
||||||
e.target.checked
|
<PermissionCheckBox
|
||||||
? onUpdatePermission({
|
isDisabled={member.permission.isOwner || !userManage}
|
||||||
id: member.tmbId!,
|
per={TeamDatasetCreatePermissionVal}
|
||||||
type: 'add',
|
clbPer={member.permission}
|
||||||
per: 'write'
|
id={member.tmbId!}
|
||||||
})
|
/>
|
||||||
: onUpdatePermission({
|
<PermissionCheckBox
|
||||||
id: member.tmbId!,
|
isDisabled={member.permission.isOwner || !userManage}
|
||||||
type: 'remove',
|
per={TeamApikeyCreatePermissionVal}
|
||||||
per: 'write'
|
clbPer={member.permission}
|
||||||
})
|
id={member.tmbId!}
|
||||||
}
|
/>
|
||||||
/>
|
<PermissionCheckBox
|
||||||
</Box>
|
isDisabled={member.permission.isOwner || !userInfo?.permission.isOwner}
|
||||||
</Td>
|
per={TeamManagePermissionVal}
|
||||||
<Td>
|
clbPer={member.permission}
|
||||||
<Box mx="auto" w="fit-content">
|
id={member.tmbId!}
|
||||||
<Checkbox
|
/>
|
||||||
isDisabled={member.permission.isOwner || !userInfo?.permission.isOwner}
|
|
||||||
isChecked={member.permission.hasManagePer}
|
|
||||||
onChange={(e) =>
|
|
||||||
e.target.checked
|
|
||||||
? onUpdatePermission({
|
|
||||||
id: member.tmbId!,
|
|
||||||
type: 'add',
|
|
||||||
per: 'manage'
|
|
||||||
})
|
|
||||||
: onUpdatePermission({
|
|
||||||
id: member.tmbId!,
|
|
||||||
type: 'remove',
|
|
||||||
per: 'manage'
|
|
||||||
})
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
</Box>
|
|
||||||
</Td>
|
|
||||||
<Td>
|
<Td>
|
||||||
{hasDeletePer(member.permission) &&
|
{hasDeletePer(member.permission) &&
|
||||||
userInfo?.team.tmbId !== member.tmbId && (
|
userInfo?.team.tmbId !== member.tmbId && (
|
||||||
@@ -268,7 +304,6 @@ function PermissionManage({
|
|||||||
</Tr>
|
</Tr>
|
||||||
))}
|
))}
|
||||||
</>
|
</>
|
||||||
|
|
||||||
<>
|
<>
|
||||||
<Tr borderBottom={'1px solid'} borderColor={'myGray.200'} />
|
<Tr borderBottom={'1px solid'} borderColor={'myGray.200'} />
|
||||||
<Tr userSelect={'none'}>
|
<Tr userSelect={'none'}>
|
||||||
@@ -286,40 +321,30 @@ function PermissionManage({
|
|||||||
<Td pl={10}>
|
<Td pl={10}>
|
||||||
<MemberTag name={org.name} avatar={org.avatar} />
|
<MemberTag name={org.name} avatar={org.avatar} />
|
||||||
</Td>
|
</Td>
|
||||||
<Td>
|
<PermissionCheckBox
|
||||||
<Box mx="auto" w="fit-content">
|
isDisabled={org.permission.isOwner || !userManage}
|
||||||
<Checkbox
|
per={TeamAppCreatePermissionVal}
|
||||||
isDisabled={!userManage}
|
clbPer={org.permission}
|
||||||
isChecked={org.permission.hasWritePer}
|
id={org.orgId!}
|
||||||
onChange={(e) =>
|
/>
|
||||||
e.target.checked
|
<PermissionCheckBox
|
||||||
? onUpdatePermission({ id: org.orgId!, type: 'add', per: 'write' })
|
isDisabled={org.permission.isOwner || !userManage}
|
||||||
: onUpdatePermission({
|
per={TeamDatasetCreatePermissionVal}
|
||||||
id: org.orgId!,
|
clbPer={org.permission}
|
||||||
type: 'remove',
|
id={org.orgId!}
|
||||||
per: 'write'
|
/>
|
||||||
})
|
<PermissionCheckBox
|
||||||
}
|
isDisabled={org.permission.isOwner || !userManage}
|
||||||
/>
|
per={TeamApikeyCreatePermissionVal}
|
||||||
</Box>
|
clbPer={org.permission}
|
||||||
</Td>
|
id={org.orgId!}
|
||||||
<Td>
|
/>
|
||||||
<Box mx="auto" w="fit-content">
|
<PermissionCheckBox
|
||||||
<Checkbox
|
isDisabled={org.permission.isOwner || !userInfo?.permission.isOwner}
|
||||||
isDisabled={!userInfo?.permission.isOwner}
|
per={TeamManagePermissionVal}
|
||||||
isChecked={org.permission.hasManagePer}
|
clbPer={org.permission}
|
||||||
onChange={(e) =>
|
id={org.orgId!}
|
||||||
e.target.checked
|
/>
|
||||||
? onUpdatePermission({ id: org.orgId!, type: 'add', per: 'manage' })
|
|
||||||
: onUpdatePermission({
|
|
||||||
id: org.orgId!,
|
|
||||||
type: 'remove',
|
|
||||||
per: 'manage'
|
|
||||||
})
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
</Box>
|
|
||||||
</Td>
|
|
||||||
<Td>
|
<Td>
|
||||||
{hasDeletePer(org.permission) && (
|
{hasDeletePer(org.permission) && (
|
||||||
<Box mx="auto" w="fit-content">
|
<Box mx="auto" w="fit-content">
|
||||||
@@ -358,48 +383,30 @@ function PermissionManage({
|
|||||||
avatar={group.avatar}
|
avatar={group.avatar}
|
||||||
/>
|
/>
|
||||||
</Td>
|
</Td>
|
||||||
<Td>
|
<PermissionCheckBox
|
||||||
<Box mx="auto" w="fit-content">
|
isDisabled={group.permission.isOwner || !userManage}
|
||||||
<Checkbox
|
per={TeamAppCreatePermissionVal}
|
||||||
isDisabled={!userManage}
|
clbPer={group.permission}
|
||||||
isChecked={group.permission.hasWritePer}
|
id={group.groupId!}
|
||||||
onChange={(e) =>
|
/>
|
||||||
e.target.checked
|
<PermissionCheckBox
|
||||||
? onUpdatePermission({
|
isDisabled={group.permission.isOwner || !userManage}
|
||||||
id: group.groupId!,
|
per={TeamDatasetCreatePermissionVal}
|
||||||
type: 'add',
|
clbPer={group.permission}
|
||||||
per: 'write'
|
id={group.groupId!}
|
||||||
})
|
/>
|
||||||
: onUpdatePermission({
|
<PermissionCheckBox
|
||||||
id: group.groupId!,
|
isDisabled={group.permission.isOwner || !userManage}
|
||||||
type: 'remove',
|
per={TeamApikeyCreatePermissionVal}
|
||||||
per: 'write'
|
clbPer={group.permission}
|
||||||
})
|
id={group.groupId!}
|
||||||
}
|
/>
|
||||||
/>
|
<PermissionCheckBox
|
||||||
</Box>
|
isDisabled={group.permission.isOwner || !userInfo?.permission.isOwner}
|
||||||
</Td>
|
per={TeamManagePermissionVal}
|
||||||
<Td>
|
clbPer={group.permission}
|
||||||
<Box mx="auto" w="fit-content">
|
id={group.groupId!}
|
||||||
<Checkbox
|
/>
|
||||||
isDisabled={!userInfo?.permission.isOwner}
|
|
||||||
isChecked={group.permission.hasManagePer}
|
|
||||||
onChange={(e) =>
|
|
||||||
e.target.checked
|
|
||||||
? onUpdatePermission({
|
|
||||||
id: group.groupId!,
|
|
||||||
type: 'add',
|
|
||||||
per: 'manage'
|
|
||||||
})
|
|
||||||
: onUpdatePermission({
|
|
||||||
id: group.groupId!,
|
|
||||||
type: 'remove',
|
|
||||||
per: 'manage'
|
|
||||||
})
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
</Box>
|
|
||||||
</Td>
|
|
||||||
<Td>
|
<Td>
|
||||||
{hasDeletePer(group.permission) && (
|
{hasDeletePer(group.permission) && (
|
||||||
<Box mx="auto" w="fit-content">
|
<Box mx="auto" w="fit-content">
|
||||||
|
|||||||
@@ -13,7 +13,10 @@ import {
|
|||||||
SelectOptionsComponent
|
SelectOptionsComponent
|
||||||
} from '@/components/core/chat/components/Interactive/InteractiveComponents';
|
} from '@/components/core/chat/components/Interactive/InteractiveComponents';
|
||||||
import { UserInputInteractive } from '@fastgpt/global/core/workflow/template/system/interactive/type';
|
import { UserInputInteractive } from '@fastgpt/global/core/workflow/template/system/interactive/type';
|
||||||
import { initWorkflowEdgeStatus } from '@fastgpt/global/core/workflow/runtime/utils';
|
import {
|
||||||
|
getLastInteractiveValue,
|
||||||
|
initWorkflowEdgeStatus
|
||||||
|
} from '@fastgpt/global/core/workflow/runtime/utils';
|
||||||
import { ChatItemType, UserChatItemValueItemType } from '@fastgpt/global/core/chat/type';
|
import { ChatItemType, UserChatItemValueItemType } from '@fastgpt/global/core/chat/type';
|
||||||
import { ChatItemValueTypeEnum, ChatRoleEnum } from '@fastgpt/global/core/chat/constants';
|
import { ChatItemValueTypeEnum, ChatRoleEnum } from '@fastgpt/global/core/chat/constants';
|
||||||
|
|
||||||
@@ -130,10 +133,11 @@ const NodeDebugResponse = ({ nodeId, debugResult }: NodeDebugResponseProps) => {
|
|||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
|
const lastInteractive = getLastInteractiveValue(mockHistory);
|
||||||
onNextNodeDebug({
|
onNextNodeDebug({
|
||||||
...workflowDebugData,
|
...workflowDebugData,
|
||||||
// Rewrite runtimeEdges
|
// Rewrite runtimeEdges
|
||||||
runtimeEdges: initWorkflowEdgeStatus(workflowDebugData.runtimeEdges, mockHistory),
|
runtimeEdges: initWorkflowEdgeStatus(workflowDebugData.runtimeEdges, lastInteractive),
|
||||||
query: updatedQuery,
|
query: updatedQuery,
|
||||||
history: mockHistory
|
history: mockHistory
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ import { useSystem } from '@fastgpt/web/hooks/useSystem';
|
|||||||
import { useChatStore } from '@/web/core/chat/context/useChatStore';
|
import { useChatStore } from '@/web/core/chat/context/useChatStore';
|
||||||
import { RequireOnlyOne } from '@fastgpt/global/common/type/utils';
|
import { RequireOnlyOne } from '@fastgpt/global/common/type/utils';
|
||||||
import UserBox from '@fastgpt/web/components/common/UserBox';
|
import UserBox from '@fastgpt/web/components/common/UserBox';
|
||||||
|
import { PermissionValueType } from '@fastgpt/global/support/permission/type';
|
||||||
const HttpEditModal = dynamic(() => import('./HttpPluginEditModal'));
|
const HttpEditModal = dynamic(() => import('./HttpPluginEditModal'));
|
||||||
|
|
||||||
const ListItem = () => {
|
const ListItem = () => {
|
||||||
@@ -429,7 +430,7 @@ const ListItem = () => {
|
|||||||
members?: string[];
|
members?: string[];
|
||||||
groups?: string[];
|
groups?: string[];
|
||||||
orgs?: string[];
|
orgs?: string[];
|
||||||
permission: number;
|
permission: PermissionValueType;
|
||||||
}) =>
|
}) =>
|
||||||
postUpdateAppCollaborators({
|
postUpdateAppCollaborators({
|
||||||
...props,
|
...props,
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import React, { Dispatch } from 'react';
|
import React, { Dispatch } from 'react';
|
||||||
import { FormControl, Box, Input, Button } from '@chakra-ui/react';
|
import { FormControl, Box, Input, Button } from '@chakra-ui/react';
|
||||||
import { useForm } from 'react-hook-form';
|
import { useForm } from 'react-hook-form';
|
||||||
import { LoginPageTypeEnum, PasswordRule } from '@/web/support/user/login/constants';
|
import { LoginPageTypeEnum, checkPasswordRule } from '@/web/support/user/login/constants';
|
||||||
import { postFindPassword } from '@/web/support/user/api';
|
import { postFindPassword } from '@/web/support/user/api';
|
||||||
import { useSendCode } from '@/web/support/user/hooks/useSendCode';
|
import { useSendCode } from '@/web/support/user/hooks/useSendCode';
|
||||||
import type { ResLogin } from '@/global/support/api/userRes.d';
|
import type { ResLogin } from '@/global/support/api/userRes.d';
|
||||||
@@ -138,9 +138,11 @@ const RegisterForm = ({ setPageType, loginSuccess }: Props) => {
|
|||||||
placeholder={t('login:password_tip')}
|
placeholder={t('login:password_tip')}
|
||||||
{...register('password', {
|
{...register('password', {
|
||||||
required: true,
|
required: true,
|
||||||
pattern: {
|
validate: (val) => {
|
||||||
value: PasswordRule,
|
if (!checkPasswordRule(val)) {
|
||||||
message: t('login:password_tip')
|
return t('login:password_tip');
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
})}
|
})}
|
||||||
></Input>
|
></Input>
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import React, { Dispatch } from 'react';
|
import React, { Dispatch } from 'react';
|
||||||
import { FormControl, Box, Input, Button } from '@chakra-ui/react';
|
import { FormControl, Box, Input, Button } from '@chakra-ui/react';
|
||||||
import { useForm } from 'react-hook-form';
|
import { useForm } from 'react-hook-form';
|
||||||
import { LoginPageTypeEnum, PasswordRule } from '@/web/support/user/login/constants';
|
import { LoginPageTypeEnum, checkPasswordRule } from '@/web/support/user/login/constants';
|
||||||
import { postRegister } from '@/web/support/user/api';
|
import { postRegister } from '@/web/support/user/api';
|
||||||
import { useSendCode } from '@/web/support/user/hooks/useSendCode';
|
import { useSendCode } from '@/web/support/user/hooks/useSendCode';
|
||||||
import type { ResLogin } from '@/global/support/api/userRes';
|
import type { ResLogin } from '@/global/support/api/userRes';
|
||||||
@@ -166,9 +166,11 @@ const RegisterForm = ({ setPageType, loginSuccess }: Props) => {
|
|||||||
placeholder={t('login:password_tip')}
|
placeholder={t('login:password_tip')}
|
||||||
{...register('password', {
|
{...register('password', {
|
||||||
required: true,
|
required: true,
|
||||||
pattern: {
|
validate: (val) => {
|
||||||
value: PasswordRule,
|
if (!checkPasswordRule(val)) {
|
||||||
message: t('login:password_tip')
|
return t('login:password_tip');
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
})}
|
})}
|
||||||
></Input>
|
></Input>
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ const MemberTable = dynamic(() => import('@/pageComponents/account/team/MemberTa
|
|||||||
const PermissionManage = dynamic(
|
const PermissionManage = dynamic(
|
||||||
() => import('@/pageComponents/account/team/PermissionManage/index')
|
() => import('@/pageComponents/account/team/PermissionManage/index')
|
||||||
);
|
);
|
||||||
|
const OperationLogTable = dynamic(() => import('@/pageComponents/account/team/OperationLog/index'));
|
||||||
const GroupManage = dynamic(() => import('@/pageComponents/account/team/GroupManage/index'));
|
const GroupManage = dynamic(() => import('@/pageComponents/account/team/GroupManage/index'));
|
||||||
const OrgManage = dynamic(() => import('@/pageComponents/account/team/OrgManage/index'));
|
const OrgManage = dynamic(() => import('@/pageComponents/account/team/OrgManage/index'));
|
||||||
const HandleInviteModal = dynamic(
|
const HandleInviteModal = dynamic(
|
||||||
@@ -28,7 +29,8 @@ export enum TeamTabEnum {
|
|||||||
member = 'member',
|
member = 'member',
|
||||||
org = 'org',
|
org = 'org',
|
||||||
group = 'group',
|
group = 'group',
|
||||||
permission = 'permission'
|
permission = 'permission',
|
||||||
|
operationLog = 'operationLog'
|
||||||
}
|
}
|
||||||
|
|
||||||
const Team = () => {
|
const Team = () => {
|
||||||
@@ -57,7 +59,8 @@ const Team = () => {
|
|||||||
{ label: t('account_team:member'), value: TeamTabEnum.member },
|
{ label: t('account_team:member'), value: TeamTabEnum.member },
|
||||||
{ label: t('account_team:org'), value: TeamTabEnum.org },
|
{ label: t('account_team:org'), value: TeamTabEnum.org },
|
||||||
{ label: t('account_team:group'), value: TeamTabEnum.group },
|
{ label: t('account_team:group'), value: TeamTabEnum.group },
|
||||||
{ label: t('account_team:permission'), value: TeamTabEnum.permission }
|
{ label: t('account_team:permission'), value: TeamTabEnum.permission },
|
||||||
|
{ label: t('account_team:operation_log'), value: TeamTabEnum.operationLog }
|
||||||
]}
|
]}
|
||||||
px={'1rem'}
|
px={'1rem'}
|
||||||
value={teamTab}
|
value={teamTab}
|
||||||
@@ -150,6 +153,7 @@ const Team = () => {
|
|||||||
{teamTab === TeamTabEnum.org && <OrgManage Tabs={Tabs} />}
|
{teamTab === TeamTabEnum.org && <OrgManage Tabs={Tabs} />}
|
||||||
{teamTab === TeamTabEnum.group && <GroupManage Tabs={Tabs} />}
|
{teamTab === TeamTabEnum.group && <GroupManage Tabs={Tabs} />}
|
||||||
{teamTab === TeamTabEnum.permission && <PermissionManage Tabs={Tabs} />}
|
{teamTab === TeamTabEnum.permission && <PermissionManage Tabs={Tabs} />}
|
||||||
|
{teamTab === TeamTabEnum.operationLog && <OperationLogTable Tabs={Tabs} />}
|
||||||
</Box>
|
</Box>
|
||||||
</Flex>
|
</Flex>
|
||||||
{invitelinkid && <HandleInviteModal invitelinkid={invitelinkid} />}
|
{invitelinkid && <HandleInviteModal invitelinkid={invitelinkid} />}
|
||||||
|
|||||||
48
projects/app/src/pages/api/admin/initv495.ts
Normal file
48
projects/app/src/pages/api/admin/initv495.ts
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
import { NextAPI } from '@/service/middleware/entry';
|
||||||
|
import { authCert } from '@fastgpt/service/support/permission/auth/common';
|
||||||
|
import { NextApiRequest, NextApiResponse } from 'next';
|
||||||
|
import { MongoResourcePermission } from '@fastgpt/service/support/permission/schema';
|
||||||
|
import { TeamPermission } from '@fastgpt/global/support/permission/user/controller';
|
||||||
|
import {
|
||||||
|
TeamApikeyCreatePermissionVal,
|
||||||
|
TeamAppCreatePermissionVal,
|
||||||
|
TeamDatasetCreatePermissionVal
|
||||||
|
} from '@fastgpt/global/support/permission/user/constant';
|
||||||
|
import { retryFn } from '@fastgpt/global/common/system/utils';
|
||||||
|
|
||||||
|
async function handler(req: NextApiRequest, _res: NextApiResponse) {
|
||||||
|
await authCert({ req, authRoot: true });
|
||||||
|
// 更新团队权限:
|
||||||
|
// 目前所有有 TeamWritePermission 的,都需要添加三个新的权限。
|
||||||
|
|
||||||
|
const rps = await MongoResourcePermission.find({
|
||||||
|
resourceType: 'team',
|
||||||
|
teamId: { $exists: true },
|
||||||
|
resourceId: null
|
||||||
|
});
|
||||||
|
|
||||||
|
for await (const rp of rps) {
|
||||||
|
const per = new TeamPermission({ per: rp.permission });
|
||||||
|
console.log(per.hasWritePer, per.value);
|
||||||
|
if (per.hasWritePer) {
|
||||||
|
const newPer = per.addPer(
|
||||||
|
TeamAppCreatePermissionVal,
|
||||||
|
TeamDatasetCreatePermissionVal,
|
||||||
|
TeamApikeyCreatePermissionVal
|
||||||
|
);
|
||||||
|
rp.permission = newPer.value;
|
||||||
|
|
||||||
|
try {
|
||||||
|
await retryFn(async () => {
|
||||||
|
await rp.save();
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
console.log('更新权限异常', error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return { success: true };
|
||||||
|
}
|
||||||
|
|
||||||
|
export default NextAPI(handler);
|
||||||
@@ -4,6 +4,7 @@ import { authApp } from '@fastgpt/service/support/permission/app/auth';
|
|||||||
import { WritePermissionVal } from '@fastgpt/global/support/permission/constant';
|
import { WritePermissionVal } from '@fastgpt/global/support/permission/constant';
|
||||||
import { authUserPer } from '@fastgpt/service/support/permission/user/auth';
|
import { authUserPer } from '@fastgpt/service/support/permission/user/auth';
|
||||||
import { onCreateApp } from './create';
|
import { onCreateApp } from './create';
|
||||||
|
import { TeamAppCreatePermissionVal } from '@fastgpt/global/support/permission/user/constant';
|
||||||
|
|
||||||
export type copyAppQuery = {};
|
export type copyAppQuery = {};
|
||||||
|
|
||||||
@@ -17,19 +18,16 @@ async function handler(
|
|||||||
req: ApiRequestProps<copyAppBody, copyAppQuery>,
|
req: ApiRequestProps<copyAppBody, copyAppQuery>,
|
||||||
res: ApiResponseType<any>
|
res: ApiResponseType<any>
|
||||||
): Promise<copyAppResponse> {
|
): Promise<copyAppResponse> {
|
||||||
const [{ app, tmbId }] = await Promise.all([
|
const { app } = await authApp({
|
||||||
authApp({
|
req,
|
||||||
req,
|
authToken: true,
|
||||||
authToken: true,
|
per: WritePermissionVal,
|
||||||
per: WritePermissionVal,
|
appId: req.body.appId
|
||||||
appId: req.body.appId
|
});
|
||||||
}),
|
|
||||||
authUserPer({
|
const { tmbId } = app.parentId
|
||||||
req,
|
? await authApp({ req, appId: app.parentId, per: TeamAppCreatePermissionVal, authToken: true })
|
||||||
authToken: true,
|
: await authUserPer({ req, authToken: true, per: TeamAppCreatePermissionVal });
|
||||||
per: WritePermissionVal
|
|
||||||
})
|
|
||||||
]);
|
|
||||||
|
|
||||||
const appId = await onCreateApp({
|
const appId = await onCreateApp({
|
||||||
parentId: app.parentId,
|
parentId: app.parentId,
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ import { CommonErrEnum } from '@fastgpt/global/common/error/code/common';
|
|||||||
import { MongoTeamMember } from '@fastgpt/service/support/user/team/teamMemberSchema';
|
import { MongoTeamMember } from '@fastgpt/service/support/user/team/teamMemberSchema';
|
||||||
import { pushTrack } from '@fastgpt/service/common/middle/tracks/utils';
|
import { pushTrack } from '@fastgpt/service/common/middle/tracks/utils';
|
||||||
import { refreshSourceAvatar } from '@fastgpt/service/common/file/image/controller';
|
import { refreshSourceAvatar } from '@fastgpt/service/common/file/image/controller';
|
||||||
|
import { TeamAppCreatePermissionVal } from '@fastgpt/global/support/permission/user/constant';
|
||||||
|
|
||||||
export type CreateAppBody = {
|
export type CreateAppBody = {
|
||||||
parentId?: ParentIdType;
|
parentId?: ParentIdType;
|
||||||
@@ -36,18 +37,15 @@ async function handler(req: ApiRequestProps<CreateAppBody>) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 凭证校验
|
// 凭证校验
|
||||||
const [{ teamId, tmbId, userId }] = await Promise.all([
|
const { teamId, tmbId, userId } = parentId
|
||||||
authUserPer({ req, authToken: true, per: WritePermissionVal }),
|
? await authApp({ req, appId: parentId, per: TeamAppCreatePermissionVal, authToken: true })
|
||||||
...(parentId
|
: await authUserPer({ req, authToken: true, per: TeamAppCreatePermissionVal });
|
||||||
? [authApp({ req, appId: parentId, per: WritePermissionVal, authToken: true })]
|
|
||||||
: [])
|
|
||||||
]);
|
|
||||||
|
|
||||||
// 上限校验
|
// 上限校验
|
||||||
await checkTeamAppLimit(teamId);
|
await checkTeamAppLimit(teamId);
|
||||||
const tmb = await MongoTeamMember.findById({ _id: tmbId }, 'userId').populate<{
|
const tmb = await MongoTeamMember.findById({ _id: tmbId }, 'userId').populate<{
|
||||||
user: { avatar: string; username: string };
|
user: { username: string };
|
||||||
}>('user', 'avatar username');
|
}>('user', 'username');
|
||||||
|
|
||||||
// 创建app
|
// 创建app
|
||||||
const appId = await onCreateApp({
|
const appId = await onCreateApp({
|
||||||
@@ -60,7 +58,7 @@ async function handler(req: ApiRequestProps<CreateAppBody>) {
|
|||||||
chatConfig,
|
chatConfig,
|
||||||
teamId,
|
teamId,
|
||||||
tmbId,
|
tmbId,
|
||||||
userAvatar: tmb?.user?.avatar,
|
userAvatar: tmb?.avatar,
|
||||||
username: tmb?.user?.username
|
username: tmb?.user?.username
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ import { mongoSessionRun } from '@fastgpt/service/common/mongo/sessionRun';
|
|||||||
import { CommonErrEnum } from '@fastgpt/global/common/error/code/common';
|
import { CommonErrEnum } from '@fastgpt/global/common/error/code/common';
|
||||||
import { syncCollaborators } from '@fastgpt/service/support/permission/inheritPermission';
|
import { syncCollaborators } from '@fastgpt/service/support/permission/inheritPermission';
|
||||||
import { getResourceClbsAndGroups } from '@fastgpt/service/support/permission/controller';
|
import { getResourceClbsAndGroups } from '@fastgpt/service/support/permission/controller';
|
||||||
import { TeamWritePermissionVal } from '@fastgpt/global/support/permission/user/constant';
|
import { TeamAppCreatePermissionVal } from '@fastgpt/global/support/permission/user/constant';
|
||||||
import { MongoResourcePermission } from '@fastgpt/service/support/permission/schema';
|
import { MongoResourcePermission } from '@fastgpt/service/support/permission/schema';
|
||||||
|
|
||||||
export type CreateAppFolderBody = {
|
export type CreateAppFolderBody = {
|
||||||
@@ -33,21 +33,9 @@ async function handler(req: ApiRequestProps<CreateAppFolderBody>) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 凭证校验
|
// 凭证校验
|
||||||
const { teamId, tmbId } = await authUserPer({
|
const { teamId, tmbId } = parentId
|
||||||
req,
|
? await authApp({ req, appId: parentId, per: TeamAppCreatePermissionVal, authToken: true })
|
||||||
authToken: true,
|
: await authUserPer({ req, authToken: true, per: TeamAppCreatePermissionVal });
|
||||||
per: TeamWritePermissionVal
|
|
||||||
});
|
|
||||||
|
|
||||||
if (parentId) {
|
|
||||||
// if it is not a root folder
|
|
||||||
await authApp({
|
|
||||||
req,
|
|
||||||
appId: parentId,
|
|
||||||
per: WritePermissionVal,
|
|
||||||
authToken: true
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create app
|
// Create app
|
||||||
await mongoSessionRun(async (session) => {
|
await mongoSessionRun(async (session) => {
|
||||||
|
|||||||
@@ -9,6 +9,8 @@ import { onCreateApp, type CreateAppBody } from '../create';
|
|||||||
import { AppSchema } from '@fastgpt/global/core/app/type';
|
import { AppSchema } from '@fastgpt/global/core/app/type';
|
||||||
import { AppTypeEnum } from '@fastgpt/global/core/app/constants';
|
import { AppTypeEnum } from '@fastgpt/global/core/app/constants';
|
||||||
import { pushTrack } from '@fastgpt/service/common/middle/tracks/utils';
|
import { pushTrack } from '@fastgpt/service/common/middle/tracks/utils';
|
||||||
|
import { authApp } from '@fastgpt/service/support/permission/app/auth';
|
||||||
|
import { TeamAppCreatePermissionVal } from '@fastgpt/global/support/permission/user/constant';
|
||||||
|
|
||||||
export type createHttpPluginQuery = {};
|
export type createHttpPluginQuery = {};
|
||||||
|
|
||||||
@@ -29,11 +31,9 @@ async function handler(
|
|||||||
return Promise.reject('缺少参数');
|
return Promise.reject('缺少参数');
|
||||||
}
|
}
|
||||||
|
|
||||||
const { teamId, tmbId, userId } = await authUserPer({
|
const { teamId, tmbId, userId } = parentId
|
||||||
req,
|
? await authApp({ req, appId: parentId, per: TeamAppCreatePermissionVal, authToken: true })
|
||||||
authToken: true,
|
: await authUserPer({ req, authToken: true, per: TeamAppCreatePermissionVal });
|
||||||
per: WritePermissionVal
|
|
||||||
});
|
|
||||||
|
|
||||||
await mongoSessionRun(async (session) => {
|
await mongoSessionRun(async (session) => {
|
||||||
// create http plugin folder
|
// create http plugin folder
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ import { ClientSession } from 'mongoose';
|
|||||||
import { mongoSessionRun } from '@fastgpt/service/common/mongo/sessionRun';
|
import { mongoSessionRun } from '@fastgpt/service/common/mongo/sessionRun';
|
||||||
import { getResourceClbsAndGroups } from '@fastgpt/service/support/permission/controller';
|
import { getResourceClbsAndGroups } from '@fastgpt/service/support/permission/controller';
|
||||||
import { authUserPer } from '@fastgpt/service/support/permission/user/auth';
|
import { authUserPer } from '@fastgpt/service/support/permission/user/auth';
|
||||||
import { TeamWritePermissionVal } from '@fastgpt/global/support/permission/user/constant';
|
import { TeamAppCreatePermissionVal } from '@fastgpt/global/support/permission/user/constant';
|
||||||
import { AppErrEnum } from '@fastgpt/global/common/error/code/app';
|
import { AppErrEnum } from '@fastgpt/global/common/error/code/app';
|
||||||
import { refreshSourceAvatar } from '@fastgpt/service/common/file/image/controller';
|
import { refreshSourceAvatar } from '@fastgpt/service/common/file/image/controller';
|
||||||
import { MongoResourcePermission } from '@fastgpt/service/support/permission/schema';
|
import { MongoResourcePermission } from '@fastgpt/service/support/permission/schema';
|
||||||
@@ -79,7 +79,7 @@ async function handler(req: ApiRequestProps<AppUpdateBody, AppUpdateQuery>) {
|
|||||||
await authUserPer({
|
await authUserPer({
|
||||||
req,
|
req,
|
||||||
authToken: true,
|
authToken: true,
|
||||||
per: TeamWritePermissionVal
|
per: TeamAppCreatePermissionVal
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -98,7 +98,7 @@ async function handler(req: NextApiRequest, res: NextApiResponse) {
|
|||||||
|
|
||||||
const isPlugin = app.type === AppTypeEnum.plugin;
|
const isPlugin = app.type === AppTypeEnum.plugin;
|
||||||
|
|
||||||
const userQuestion: UserChatItemType = (() => {
|
const userQuestion: UserChatItemType = await (async () => {
|
||||||
if (isPlugin) {
|
if (isPlugin) {
|
||||||
return getPluginRunUserQuery({
|
return getPluginRunUserQuery({
|
||||||
pluginInputs: getPluginInputsFromStoreNodes(app.modules),
|
pluginInputs: getPluginInputsFromStoreNodes(app.modules),
|
||||||
@@ -107,9 +107,9 @@ async function handler(req: NextApiRequest, res: NextApiResponse) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const latestHumanChat = chatMessages.pop() as UserChatItemType | undefined;
|
const latestHumanChat = chatMessages.pop() as UserChatItemType;
|
||||||
if (!latestHumanChat) {
|
if (!latestHumanChat) {
|
||||||
throw new Error('User question is empty');
|
return Promise.reject('User question is empty');
|
||||||
}
|
}
|
||||||
return latestHumanChat;
|
return latestHumanChat;
|
||||||
})();
|
})();
|
||||||
@@ -136,14 +136,14 @@ async function handler(req: NextApiRequest, res: NextApiResponse) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const newHistories = concatHistories(histories, chatMessages);
|
const newHistories = concatHistories(histories, chatMessages);
|
||||||
|
const interactive = getLastInteractiveValue(newHistories) || undefined;
|
||||||
// Get runtimeNodes
|
// Get runtimeNodes
|
||||||
let runtimeNodes = storeNodes2RuntimeNodes(nodes, getWorkflowEntryNodeIds(nodes, newHistories));
|
let runtimeNodes = storeNodes2RuntimeNodes(nodes, getWorkflowEntryNodeIds(nodes, interactive));
|
||||||
if (isPlugin) {
|
if (isPlugin) {
|
||||||
runtimeNodes = updatePluginInputByVariables(runtimeNodes, variables);
|
runtimeNodes = updatePluginInputByVariables(runtimeNodes, variables);
|
||||||
variables = {};
|
variables = {};
|
||||||
}
|
}
|
||||||
runtimeNodes = rewriteNodeOutputByHistories(newHistories, runtimeNodes);
|
runtimeNodes = rewriteNodeOutputByHistories(runtimeNodes, interactive);
|
||||||
|
|
||||||
const workflowResponseWrite = getWorkflowResponseWrite({
|
const workflowResponseWrite = getWorkflowResponseWrite({
|
||||||
res,
|
res,
|
||||||
@@ -175,9 +175,10 @@ async function handler(req: NextApiRequest, res: NextApiResponse) {
|
|||||||
chatId,
|
chatId,
|
||||||
responseChatItemId,
|
responseChatItemId,
|
||||||
runtimeNodes,
|
runtimeNodes,
|
||||||
runtimeEdges: initWorkflowEdgeStatus(edges, newHistories),
|
runtimeEdges: initWorkflowEdgeStatus(edges, interactive),
|
||||||
variables,
|
variables,
|
||||||
query: removeEmptyUserInput(userQuestion.value),
|
query: removeEmptyUserInput(userQuestion.value),
|
||||||
|
lastInteractive: interactive,
|
||||||
chatConfig,
|
chatConfig,
|
||||||
histories: newHistories,
|
histories: newHistories,
|
||||||
stream: true,
|
stream: true,
|
||||||
|
|||||||
@@ -6,11 +6,9 @@ import {
|
|||||||
getLLMModel,
|
getLLMModel,
|
||||||
getEmbeddingModel,
|
getEmbeddingModel,
|
||||||
getDatasetModel,
|
getDatasetModel,
|
||||||
getDefaultEmbeddingModel,
|
getDefaultEmbeddingModel
|
||||||
getVlmModel
|
|
||||||
} from '@fastgpt/service/core/ai/model';
|
} from '@fastgpt/service/core/ai/model';
|
||||||
import { checkTeamDatasetLimit } from '@fastgpt/service/support/permission/teamLimit';
|
import { checkTeamDatasetLimit } from '@fastgpt/service/support/permission/teamLimit';
|
||||||
import { WritePermissionVal } from '@fastgpt/global/support/permission/constant';
|
|
||||||
import { NextAPI } from '@/service/middleware/entry';
|
import { NextAPI } from '@/service/middleware/entry';
|
||||||
import type { ApiRequestProps } from '@fastgpt/service/type/next';
|
import type { ApiRequestProps } from '@fastgpt/service/type/next';
|
||||||
import { parseParentIdInMongo } from '@fastgpt/global/common/parentFolder/utils';
|
import { parseParentIdInMongo } from '@fastgpt/global/common/parentFolder/utils';
|
||||||
@@ -18,6 +16,7 @@ import { authDataset } from '@fastgpt/service/support/permission/dataset/auth';
|
|||||||
import { pushTrack } from '@fastgpt/service/common/middle/tracks/utils';
|
import { pushTrack } from '@fastgpt/service/common/middle/tracks/utils';
|
||||||
import { mongoSessionRun } from '@fastgpt/service/common/mongo/sessionRun';
|
import { mongoSessionRun } from '@fastgpt/service/common/mongo/sessionRun';
|
||||||
import { refreshSourceAvatar } from '@fastgpt/service/common/file/image/controller';
|
import { refreshSourceAvatar } from '@fastgpt/service/common/file/image/controller';
|
||||||
|
import { TeamDatasetCreatePermissionVal } from '@fastgpt/global/support/permission/user/constant';
|
||||||
|
|
||||||
export type DatasetCreateQuery = {};
|
export type DatasetCreateQuery = {};
|
||||||
export type DatasetCreateBody = CreateDatasetParams;
|
export type DatasetCreateBody = CreateDatasetParams;
|
||||||
@@ -41,25 +40,20 @@ async function handler(
|
|||||||
} = req.body;
|
} = req.body;
|
||||||
|
|
||||||
// auth
|
// auth
|
||||||
const [{ teamId, tmbId, userId }] = await Promise.all([
|
const { teamId, tmbId, userId } = parentId
|
||||||
authUserPer({
|
? await authDataset({
|
||||||
req,
|
req,
|
||||||
authToken: true,
|
datasetId: parentId,
|
||||||
authApiKey: true,
|
authToken: true,
|
||||||
per: WritePermissionVal
|
authApiKey: true,
|
||||||
}),
|
per: TeamDatasetCreatePermissionVal
|
||||||
...(parentId
|
})
|
||||||
? [
|
: await authUserPer({
|
||||||
authDataset({
|
req,
|
||||||
req,
|
authToken: true,
|
||||||
datasetId: parentId,
|
authApiKey: true,
|
||||||
authToken: true,
|
per: TeamDatasetCreatePermissionVal
|
||||||
authApiKey: true,
|
});
|
||||||
per: WritePermissionVal
|
|
||||||
})
|
|
||||||
]
|
|
||||||
: [])
|
|
||||||
]);
|
|
||||||
|
|
||||||
// check model valid
|
// check model valid
|
||||||
const vectorModelStore = getEmbeddingModel(vectorModel);
|
const vectorModelStore = getEmbeddingModel(vectorModel);
|
||||||
|
|||||||
@@ -5,8 +5,7 @@ import { CommonErrEnum } from '@fastgpt/global/common/error/code/common';
|
|||||||
import { authUserPer } from '@fastgpt/service/support/permission/user/auth';
|
import { authUserPer } from '@fastgpt/service/support/permission/user/auth';
|
||||||
import {
|
import {
|
||||||
OwnerPermissionVal,
|
OwnerPermissionVal,
|
||||||
PerResourceTypeEnum,
|
PerResourceTypeEnum
|
||||||
WritePermissionVal
|
|
||||||
} from '@fastgpt/global/support/permission/constant';
|
} from '@fastgpt/global/support/permission/constant';
|
||||||
import { authDataset } from '@fastgpt/service/support/permission/dataset/auth';
|
import { authDataset } from '@fastgpt/service/support/permission/dataset/auth';
|
||||||
import { mongoSessionRun } from '@fastgpt/service/common/mongo/sessionRun';
|
import { mongoSessionRun } from '@fastgpt/service/common/mongo/sessionRun';
|
||||||
@@ -16,6 +15,7 @@ import { DatasetTypeEnum } from '@fastgpt/global/core/dataset/constants';
|
|||||||
import { getResourceClbsAndGroups } from '@fastgpt/service/support/permission/controller';
|
import { getResourceClbsAndGroups } from '@fastgpt/service/support/permission/controller';
|
||||||
import { syncCollaborators } from '@fastgpt/service/support/permission/inheritPermission';
|
import { syncCollaborators } from '@fastgpt/service/support/permission/inheritPermission';
|
||||||
import { MongoResourcePermission } from '@fastgpt/service/support/permission/schema';
|
import { MongoResourcePermission } from '@fastgpt/service/support/permission/schema';
|
||||||
|
import { TeamDatasetCreatePermissionVal } from '@fastgpt/global/support/permission/user/constant';
|
||||||
export type DatasetFolderCreateQuery = {};
|
export type DatasetFolderCreateQuery = {};
|
||||||
export type DatasetFolderCreateBody = {
|
export type DatasetFolderCreateBody = {
|
||||||
parentId?: string;
|
parentId?: string;
|
||||||
@@ -33,20 +33,20 @@ async function handler(
|
|||||||
return Promise.reject(CommonErrEnum.missingParams);
|
return Promise.reject(CommonErrEnum.missingParams);
|
||||||
}
|
}
|
||||||
|
|
||||||
const { tmbId, teamId } = await authUserPer({
|
const { teamId, tmbId } = parentId
|
||||||
req,
|
? await authDataset({
|
||||||
per: WritePermissionVal,
|
req,
|
||||||
authToken: true
|
datasetId: parentId,
|
||||||
});
|
authToken: true,
|
||||||
|
authApiKey: true,
|
||||||
if (parentId) {
|
per: TeamDatasetCreatePermissionVal
|
||||||
await authDataset({
|
})
|
||||||
datasetId: parentId,
|
: await authUserPer({
|
||||||
per: WritePermissionVal,
|
req,
|
||||||
req,
|
authToken: true,
|
||||||
authToken: true
|
authApiKey: true,
|
||||||
});
|
per: TeamDatasetCreatePermissionVal
|
||||||
}
|
});
|
||||||
|
|
||||||
await mongoSessionRun(async (session) => {
|
await mongoSessionRun(async (session) => {
|
||||||
const dataset = await MongoDataset.create({
|
const dataset = await MongoDataset.create({
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ import {
|
|||||||
syncCollaborators
|
syncCollaborators
|
||||||
} from '@fastgpt/service/support/permission/inheritPermission';
|
} from '@fastgpt/service/support/permission/inheritPermission';
|
||||||
import { authUserPer } from '@fastgpt/service/support/permission/user/auth';
|
import { authUserPer } from '@fastgpt/service/support/permission/user/auth';
|
||||||
import { TeamWritePermissionVal } from '@fastgpt/global/support/permission/user/constant';
|
import { TeamDatasetCreatePermissionVal } from '@fastgpt/global/support/permission/user/constant';
|
||||||
import { DatasetErrEnum } from '@fastgpt/global/common/error/code/dataset';
|
import { DatasetErrEnum } from '@fastgpt/global/common/error/code/dataset';
|
||||||
import { MongoDatasetTraining } from '@fastgpt/service/core/dataset/training/schema';
|
import { MongoDatasetTraining } from '@fastgpt/service/core/dataset/training/schema';
|
||||||
import { MongoDatasetCollection } from '@fastgpt/service/core/dataset/collection/schema';
|
import { MongoDatasetCollection } from '@fastgpt/service/core/dataset/collection/schema';
|
||||||
@@ -104,7 +104,7 @@ async function handler(
|
|||||||
await authUserPer({
|
await authUserPer({
|
||||||
req,
|
req,
|
||||||
authToken: true,
|
authToken: true,
|
||||||
per: TeamWritePermissionVal
|
per: TeamDatasetCreatePermissionVal
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import { NextAPI } from '@/service/middleware/entry';
|
|||||||
import { ReadPermissionVal } from '@fastgpt/global/support/permission/constant';
|
import { ReadPermissionVal } from '@fastgpt/global/support/permission/constant';
|
||||||
import { defaultApp } from '@/web/core/app/constants';
|
import { defaultApp } from '@/web/core/app/constants';
|
||||||
import { WORKFLOW_MAX_RUN_TIMES } from '@fastgpt/service/core/workflow/constants';
|
import { WORKFLOW_MAX_RUN_TIMES } from '@fastgpt/service/core/workflow/constants';
|
||||||
|
import { getLastInteractiveValue } from '@fastgpt/global/core/workflow/runtime/utils';
|
||||||
|
|
||||||
async function handler(
|
async function handler(
|
||||||
req: NextApiRequest,
|
req: NextApiRequest,
|
||||||
@@ -44,6 +45,7 @@ async function handler(
|
|||||||
|
|
||||||
// auth balance
|
// auth balance
|
||||||
const { timezone, externalProvider } = await getUserChatInfoAndAuthTeamPoints(tmbId);
|
const { timezone, externalProvider } = await getUserChatInfoAndAuthTeamPoints(tmbId);
|
||||||
|
const lastInteractive = getLastInteractiveValue(history);
|
||||||
|
|
||||||
/* start process */
|
/* start process */
|
||||||
const { flowUsages, flowResponses, debugResponse, newVariables, workflowInteractiveResponse } =
|
const { flowUsages, flowResponses, debugResponse, newVariables, workflowInteractiveResponse } =
|
||||||
@@ -65,6 +67,7 @@ async function handler(
|
|||||||
},
|
},
|
||||||
runtimeNodes: nodes,
|
runtimeNodes: nodes,
|
||||||
runtimeEdges: edges,
|
runtimeEdges: edges,
|
||||||
|
lastInteractive,
|
||||||
variables,
|
variables,
|
||||||
query: query,
|
query: query,
|
||||||
chatConfig: defaultApp.chatConfig,
|
chatConfig: defaultApp.chatConfig,
|
||||||
|
|||||||
@@ -4,12 +4,10 @@ import { authUserPer } from '@fastgpt/service/support/permission/user/auth';
|
|||||||
import { getNanoid } from '@fastgpt/global/common/string/tools';
|
import { getNanoid } from '@fastgpt/global/common/string/tools';
|
||||||
import type { ApiRequestProps } from '@fastgpt/service/type/next';
|
import type { ApiRequestProps } from '@fastgpt/service/type/next';
|
||||||
import { NextAPI } from '@/service/middleware/entry';
|
import { NextAPI } from '@/service/middleware/entry';
|
||||||
import {
|
import { ManagePermissionVal } from '@fastgpt/global/support/permission/constant';
|
||||||
ManagePermissionVal,
|
|
||||||
WritePermissionVal
|
|
||||||
} from '@fastgpt/global/support/permission/constant';
|
|
||||||
import { authApp } from '@fastgpt/service/support/permission/app/auth';
|
import { authApp } from '@fastgpt/service/support/permission/app/auth';
|
||||||
import { OpenApiErrEnum } from '@fastgpt/global/common/error/code/openapi';
|
import { OpenApiErrEnum } from '@fastgpt/global/common/error/code/openapi';
|
||||||
|
import { TeamApikeyCreatePermissionVal } from '@fastgpt/global/support/permission/user/constant';
|
||||||
|
|
||||||
async function handler(req: ApiRequestProps<EditApiKeyProps>): Promise<string> {
|
async function handler(req: ApiRequestProps<EditApiKeyProps>): Promise<string> {
|
||||||
const { appId, name, limit } = req.body;
|
const { appId, name, limit } = req.body;
|
||||||
@@ -19,7 +17,7 @@ async function handler(req: ApiRequestProps<EditApiKeyProps>): Promise<string> {
|
|||||||
const { teamId, tmbId } = await authUserPer({
|
const { teamId, tmbId } = await authUserPer({
|
||||||
req,
|
req,
|
||||||
authToken: true,
|
authToken: true,
|
||||||
per: WritePermissionVal
|
per: TeamApikeyCreatePermissionVal
|
||||||
});
|
});
|
||||||
return { teamId, tmbId };
|
return { teamId, tmbId };
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -9,6 +9,8 @@ import { useIPFrequencyLimit } from '@fastgpt/service/common/middle/reqFrequency
|
|||||||
import { pushTrack } from '@fastgpt/service/common/middle/tracks/utils';
|
import { pushTrack } from '@fastgpt/service/common/middle/tracks/utils';
|
||||||
import { CommonErrEnum } from '@fastgpt/global/common/error/code/common';
|
import { CommonErrEnum } from '@fastgpt/global/common/error/code/common';
|
||||||
import { UserErrEnum } from '@fastgpt/global/common/error/code/user';
|
import { UserErrEnum } from '@fastgpt/global/common/error/code/user';
|
||||||
|
import { addOperationLog } from '@fastgpt/service/support/operationLog/addOperationLog';
|
||||||
|
import { OperationLogEventEnum } from '@fastgpt/global/support/operationLog/constants';
|
||||||
|
|
||||||
async function handler(req: NextApiRequest, res: NextApiResponse) {
|
async function handler(req: NextApiRequest, res: NextApiResponse) {
|
||||||
const { username, password } = req.body as PostLoginProps;
|
const { username, password } = req.body as PostLoginProps;
|
||||||
@@ -64,6 +66,12 @@ async function handler(req: NextApiRequest, res: NextApiResponse) {
|
|||||||
|
|
||||||
setCookie(res, token);
|
setCookie(res, token);
|
||||||
|
|
||||||
|
addOperationLog({
|
||||||
|
tmbId: userDetail.team.tmbId,
|
||||||
|
teamId: userDetail.team.teamId,
|
||||||
|
event: OperationLogEventEnum.LOGIN
|
||||||
|
});
|
||||||
|
|
||||||
return {
|
return {
|
||||||
user: userDetail,
|
user: userDetail,
|
||||||
token
|
token
|
||||||
|
|||||||
@@ -139,7 +139,7 @@ async function handler(req: NextApiRequest, res: NextApiResponse) {
|
|||||||
// Computed start hook params
|
// Computed start hook params
|
||||||
const startHookText = (() => {
|
const startHookText = (() => {
|
||||||
// Chat
|
// Chat
|
||||||
const userQuestion = chatMessages[chatMessages.length - 1] as UserChatItemType | undefined;
|
const userQuestion = chatMessages[chatMessages.length - 1] as UserChatItemType;
|
||||||
if (userQuestion) return chatValue2RuntimePrompt(userQuestion.value).text;
|
if (userQuestion) return chatValue2RuntimePrompt(userQuestion.value).text;
|
||||||
|
|
||||||
// plugin
|
// plugin
|
||||||
@@ -245,16 +245,17 @@ async function handler(req: NextApiRequest, res: NextApiResponse) {
|
|||||||
|
|
||||||
// Get chat histories
|
// Get chat histories
|
||||||
const newHistories = concatHistories(histories, chatMessages);
|
const newHistories = concatHistories(histories, chatMessages);
|
||||||
|
const interactive = getLastInteractiveValue(newHistories) || undefined;
|
||||||
|
|
||||||
// Get runtimeNodes
|
// Get runtimeNodes
|
||||||
let runtimeNodes = storeNodes2RuntimeNodes(nodes, getWorkflowEntryNodeIds(nodes, newHistories));
|
let runtimeNodes = storeNodes2RuntimeNodes(nodes, getWorkflowEntryNodeIds(nodes, interactive));
|
||||||
if (isPlugin) {
|
if (isPlugin) {
|
||||||
// Assign values to runtimeNodes using variables
|
// Assign values to runtimeNodes using variables
|
||||||
runtimeNodes = updatePluginInputByVariables(runtimeNodes, variables);
|
runtimeNodes = updatePluginInputByVariables(runtimeNodes, variables);
|
||||||
// Plugin runtime does not need global variables(It has been injected into the pluginInputNode)
|
// Plugin runtime does not need global variables(It has been injected into the pluginInputNode)
|
||||||
variables = {};
|
variables = {};
|
||||||
}
|
}
|
||||||
runtimeNodes = rewriteNodeOutputByHistories(newHistories, runtimeNodes);
|
runtimeNodes = rewriteNodeOutputByHistories(runtimeNodes, interactive);
|
||||||
|
|
||||||
const workflowResponseWrite = getWorkflowResponseWrite({
|
const workflowResponseWrite = getWorkflowResponseWrite({
|
||||||
res,
|
res,
|
||||||
@@ -288,7 +289,7 @@ async function handler(req: NextApiRequest, res: NextApiResponse) {
|
|||||||
chatId,
|
chatId,
|
||||||
responseChatItemId,
|
responseChatItemId,
|
||||||
runtimeNodes,
|
runtimeNodes,
|
||||||
runtimeEdges: initWorkflowEdgeStatus(edges, newHistories),
|
runtimeEdges: initWorkflowEdgeStatus(edges, interactive),
|
||||||
variables,
|
variables,
|
||||||
query: removeEmptyUserInput(userQuestion.value),
|
query: removeEmptyUserInput(userQuestion.value),
|
||||||
chatConfig,
|
chatConfig,
|
||||||
|
|||||||
@@ -139,7 +139,7 @@ async function handler(req: NextApiRequest, res: NextApiResponse) {
|
|||||||
// Computed start hook params
|
// Computed start hook params
|
||||||
const startHookText = (() => {
|
const startHookText = (() => {
|
||||||
// Chat
|
// Chat
|
||||||
const userQuestion = chatMessages[chatMessages.length - 1] as UserChatItemType | undefined;
|
const userQuestion = chatMessages[chatMessages.length - 1] as UserChatItemType;
|
||||||
if (userQuestion) return chatValue2RuntimePrompt(userQuestion.value).text;
|
if (userQuestion) return chatValue2RuntimePrompt(userQuestion.value).text;
|
||||||
|
|
||||||
// plugin
|
// plugin
|
||||||
@@ -245,16 +245,16 @@ async function handler(req: NextApiRequest, res: NextApiResponse) {
|
|||||||
|
|
||||||
// Get chat histories
|
// Get chat histories
|
||||||
const newHistories = concatHistories(histories, chatMessages);
|
const newHistories = concatHistories(histories, chatMessages);
|
||||||
|
const interactive = getLastInteractiveValue(newHistories) || undefined;
|
||||||
// Get runtimeNodes
|
// Get runtimeNodes
|
||||||
let runtimeNodes = storeNodes2RuntimeNodes(nodes, getWorkflowEntryNodeIds(nodes, newHistories));
|
let runtimeNodes = storeNodes2RuntimeNodes(nodes, getWorkflowEntryNodeIds(nodes, interactive));
|
||||||
if (isPlugin) {
|
if (isPlugin) {
|
||||||
// Assign values to runtimeNodes using variables
|
// Assign values to runtimeNodes using variables
|
||||||
runtimeNodes = updatePluginInputByVariables(runtimeNodes, variables);
|
runtimeNodes = updatePluginInputByVariables(runtimeNodes, variables);
|
||||||
// Plugin runtime does not need global variables(It has been injected into the pluginInputNode)
|
// Plugin runtime does not need global variables(It has been injected into the pluginInputNode)
|
||||||
variables = {};
|
variables = {};
|
||||||
}
|
}
|
||||||
runtimeNodes = rewriteNodeOutputByHistories(newHistories, runtimeNodes);
|
runtimeNodes = rewriteNodeOutputByHistories(runtimeNodes, interactive);
|
||||||
|
|
||||||
const workflowResponseWrite = getWorkflowResponseWrite({
|
const workflowResponseWrite = getWorkflowResponseWrite({
|
||||||
res,
|
res,
|
||||||
@@ -288,15 +288,17 @@ async function handler(req: NextApiRequest, res: NextApiResponse) {
|
|||||||
chatId,
|
chatId,
|
||||||
responseChatItemId,
|
responseChatItemId,
|
||||||
runtimeNodes,
|
runtimeNodes,
|
||||||
runtimeEdges: initWorkflowEdgeStatus(edges, newHistories),
|
runtimeEdges: initWorkflowEdgeStatus(edges, interactive),
|
||||||
variables,
|
variables,
|
||||||
query: removeEmptyUserInput(userQuestion.value),
|
query: removeEmptyUserInput(userQuestion.value),
|
||||||
|
lastInteractive: interactive,
|
||||||
chatConfig,
|
chatConfig,
|
||||||
histories: newHistories,
|
histories: newHistories,
|
||||||
stream,
|
stream,
|
||||||
maxRunTimes: WORKFLOW_MAX_RUN_TIMES,
|
maxRunTimes: WORKFLOW_MAX_RUN_TIMES,
|
||||||
workflowStreamResponse: workflowResponseWrite,
|
workflowStreamResponse: workflowResponseWrite,
|
||||||
version: 'v2'
|
version: 'v2',
|
||||||
|
responseDetail
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return Promise.reject('您的工作流版本过低,请重新发布一次');
|
return Promise.reject('您的工作流版本过低,请重新发布一次');
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ import MyIcon from '@fastgpt/web/components/common/Icon';
|
|||||||
import TemplateMarketModal from '@/pageComponents/app/list/TemplateMarketModal';
|
import TemplateMarketModal from '@/pageComponents/app/list/TemplateMarketModal';
|
||||||
import MyImage from '@fastgpt/web/components/common/Image/MyImage';
|
import MyImage from '@fastgpt/web/components/common/Image/MyImage';
|
||||||
import JsonImportModal from '@/pageComponents/app/list/JsonImportModal';
|
import JsonImportModal from '@/pageComponents/app/list/JsonImportModal';
|
||||||
|
import { PermissionValueType } from '@fastgpt/global/support/permission/type';
|
||||||
|
|
||||||
const CreateModal = dynamic(() => import('@/pageComponents/app/list/CreateModal'));
|
const CreateModal = dynamic(() => import('@/pageComponents/app/list/CreateModal'));
|
||||||
const EditFolderModal = dynamic(
|
const EditFolderModal = dynamic(
|
||||||
@@ -213,7 +214,7 @@ const MyApps = () => {
|
|||||||
|
|
||||||
{(folderDetail
|
{(folderDetail
|
||||||
? folderDetail.permission.hasWritePer && folderDetail?.type !== AppTypeEnum.httpPlugin
|
? folderDetail.permission.hasWritePer && folderDetail?.type !== AppTypeEnum.httpPlugin
|
||||||
: userInfo?.team.permission.hasWritePer) && (
|
: userInfo?.team.permission.hasAppCreatePer) && (
|
||||||
<MyMenu
|
<MyMenu
|
||||||
size="md"
|
size="md"
|
||||||
Button={
|
Button={
|
||||||
@@ -327,7 +328,7 @@ const MyApps = () => {
|
|||||||
}: {
|
}: {
|
||||||
members?: string[];
|
members?: string[];
|
||||||
groups?: string[];
|
groups?: string[];
|
||||||
permission: number;
|
permission: PermissionValueType;
|
||||||
}) => {
|
}) => {
|
||||||
return postUpdateAppCollaborators({
|
return postUpdateAppCollaborators({
|
||||||
members,
|
members,
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ import { DatasetTypeEnum } from '@fastgpt/global/core/dataset/constants';
|
|||||||
import { useToast } from '@fastgpt/web/hooks/useToast';
|
import { useToast } from '@fastgpt/web/hooks/useToast';
|
||||||
import MyBox from '@fastgpt/web/components/common/MyBox';
|
import MyBox from '@fastgpt/web/components/common/MyBox';
|
||||||
import { useSystemStore } from '@/web/common/system/useSystemStore';
|
import { useSystemStore } from '@/web/common/system/useSystemStore';
|
||||||
|
import { PermissionValueType } from '@fastgpt/global/support/permission/type';
|
||||||
|
|
||||||
const EditFolderModal = dynamic(
|
const EditFolderModal = dynamic(
|
||||||
() => import('@fastgpt/web/components/common/MyModal/EditFolderModal')
|
() => import('@fastgpt/web/components/common/MyModal/EditFolderModal')
|
||||||
@@ -138,7 +139,7 @@ const Dataset = () => {
|
|||||||
|
|
||||||
{(folderDetail
|
{(folderDetail
|
||||||
? folderDetail.permission.hasWritePer
|
? folderDetail.permission.hasWritePer
|
||||||
: userInfo?.team?.permission.hasWritePer) && (
|
: userInfo?.team?.permission.hasDatasetCreatePer) && (
|
||||||
<Box pl={[0, 4]}>
|
<Box pl={[0, 4]}>
|
||||||
<MyMenu
|
<MyMenu
|
||||||
size="md"
|
size="md"
|
||||||
@@ -248,7 +249,7 @@ const Dataset = () => {
|
|||||||
}: {
|
}: {
|
||||||
members?: string[];
|
members?: string[];
|
||||||
groups?: string[];
|
groups?: string[];
|
||||||
permission: number;
|
permission: PermissionValueType;
|
||||||
}) =>
|
}) =>
|
||||||
postUpdateDatasetCollaborators({
|
postUpdateDatasetCollaborators({
|
||||||
members,
|
members,
|
||||||
|
|||||||
@@ -33,9 +33,21 @@ const reduceQueue = () => {
|
|||||||
|
|
||||||
return global.qaQueueLen === 0;
|
return global.qaQueueLen === 0;
|
||||||
};
|
};
|
||||||
|
const reduceQueueAndReturn = (delay = 0) => {
|
||||||
|
reduceQueue();
|
||||||
|
if (delay) {
|
||||||
|
setTimeout(() => {
|
||||||
|
generateQA();
|
||||||
|
}, delay);
|
||||||
|
} else {
|
||||||
|
generateQA();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
export async function generateQA(): Promise<any> {
|
export async function generateQA(): Promise<any> {
|
||||||
const max = global.systemEnv?.qaMaxProcess || 10;
|
const max = global.systemEnv?.qaMaxProcess || 10;
|
||||||
|
addLog.debug(`[QA Queue] Queue size: ${global.qaQueueLen}`);
|
||||||
|
|
||||||
if (global.qaQueueLen >= max) return;
|
if (global.qaQueueLen >= max) return;
|
||||||
global.qaQueueLen++;
|
global.qaQueueLen++;
|
||||||
|
|
||||||
@@ -98,14 +110,12 @@ export async function generateQA(): Promise<any> {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (error) {
|
if (error) {
|
||||||
reduceQueue();
|
return reduceQueueAndReturn();
|
||||||
return generateQA();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// auth balance
|
// auth balance
|
||||||
if (!(await checkTeamAiPointsAndLock(data.teamId))) {
|
if (!(await checkTeamAiPointsAndLock(data.teamId))) {
|
||||||
reduceQueue();
|
return reduceQueueAndReturn();
|
||||||
return generateQA();
|
|
||||||
}
|
}
|
||||||
addLog.info(`[QA Queue] Start`);
|
addLog.info(`[QA Queue] Start`);
|
||||||
|
|
||||||
@@ -137,14 +147,8 @@ ${replaceVariable(Prompt_AgentQA.fixedText, { text })}`;
|
|||||||
|
|
||||||
const qaArr = formatSplitText({ answer, rawText: text, llmModel: modelData }); // 格式化后的QA对
|
const qaArr = formatSplitText({ answer, rawText: text, llmModel: modelData }); // 格式化后的QA对
|
||||||
|
|
||||||
addLog.info(`[QA Queue] Finish`, {
|
|
||||||
time: Date.now() - startTime,
|
|
||||||
splitLength: qaArr.length,
|
|
||||||
usage: chatResponse.usage
|
|
||||||
});
|
|
||||||
|
|
||||||
// get vector and insert
|
// get vector and insert
|
||||||
const { insertLen } = await pushDataListToTrainingQueueByCollectionId({
|
await pushDataListToTrainingQueueByCollectionId({
|
||||||
teamId: data.teamId,
|
teamId: data.teamId,
|
||||||
tmbId: data.tmbId,
|
tmbId: data.tmbId,
|
||||||
collectionId: data.collectionId,
|
collectionId: data.collectionId,
|
||||||
@@ -160,21 +164,21 @@ ${replaceVariable(Prompt_AgentQA.fixedText, { text })}`;
|
|||||||
await MongoDatasetTraining.findByIdAndDelete(data._id);
|
await MongoDatasetTraining.findByIdAndDelete(data._id);
|
||||||
|
|
||||||
// add bill
|
// add bill
|
||||||
if (insertLen > 0) {
|
pushQAUsage({
|
||||||
pushQAUsage({
|
teamId: data.teamId,
|
||||||
teamId: data.teamId,
|
tmbId: data.tmbId,
|
||||||
tmbId: data.tmbId,
|
inputTokens: await countGptMessagesTokens(messages),
|
||||||
inputTokens: await countGptMessagesTokens(messages),
|
outputTokens: await countPromptTokens(answer),
|
||||||
outputTokens: await countPromptTokens(answer),
|
billId: data.billId,
|
||||||
billId: data.billId,
|
model: modelData.model
|
||||||
model: modelData.model
|
});
|
||||||
});
|
addLog.info(`[QA Queue] Finish`, {
|
||||||
} else {
|
time: Date.now() - startTime,
|
||||||
addLog.info(`QA result 0:`, { answer });
|
splitLength: qaArr.length,
|
||||||
}
|
usage: chatResponse.usage
|
||||||
|
});
|
||||||
|
|
||||||
reduceQueue();
|
return reduceQueueAndReturn();
|
||||||
generateQA();
|
|
||||||
} catch (err: any) {
|
} catch (err: any) {
|
||||||
addLog.error(`[QA Queue] Error`, err);
|
addLog.error(`[QA Queue] Error`, err);
|
||||||
await MongoDatasetTraining.updateOne(
|
await MongoDatasetTraining.updateOne(
|
||||||
@@ -188,9 +192,7 @@ ${replaceVariable(Prompt_AgentQA.fixedText, { text })}`;
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
setTimeout(() => {
|
return reduceQueueAndReturn(1000);
|
||||||
generateQA();
|
|
||||||
}, 1000);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -35,6 +35,8 @@ const reduceQueueAndReturn = (delay = 0) => {
|
|||||||
/* 索引生成队列。每导入一次,就是一个单独的线程 */
|
/* 索引生成队列。每导入一次,就是一个单独的线程 */
|
||||||
export async function generateVector(): Promise<any> {
|
export async function generateVector(): Promise<any> {
|
||||||
const max = global.systemEnv?.vectorMaxProcess || 10;
|
const max = global.systemEnv?.vectorMaxProcess || 10;
|
||||||
|
addLog.debug(`[Vector Queue] Queue size: ${global.vectorQueueLen}`);
|
||||||
|
|
||||||
if (global.vectorQueueLen >= max) return;
|
if (global.vectorQueueLen >= max) return;
|
||||||
global.vectorQueueLen++;
|
global.vectorQueueLen++;
|
||||||
const start = Date.now();
|
const start = Date.now();
|
||||||
|
|||||||
@@ -5,5 +5,21 @@ export enum LoginPageTypeEnum {
|
|||||||
wechat = 'wechat'
|
wechat = 'wechat'
|
||||||
}
|
}
|
||||||
|
|
||||||
export const PasswordRule =
|
export const checkPasswordRule = (password: string) => {
|
||||||
/^(?:(?=.*\d)(?=.*[a-z])|(?=.*\d)(?=.*[A-Z])|(?=.*\d)(?=.*[!@#$%^&*_])|(?=.*[a-z])(?=.*[A-Z])|(?=.*[a-z])(?=.*[!@#$%^&*_])|(?=.*[A-Z])(?=.*[!@#$%^&*_]))[\dA-Za-z!@#$%^&*_]{6,}$/;
|
const patterns = [
|
||||||
|
/\d/, // Contains digits
|
||||||
|
/[a-z]/, // Contains lowercase letters
|
||||||
|
/[A-Z]/, // Contains uppercase letters
|
||||||
|
/[!@#$%^&*()_+=-]/ // Contains special characters
|
||||||
|
];
|
||||||
|
const validChars = /^[\dA-Za-z!@#$%^&*()_+=-]{6,100}$/;
|
||||||
|
|
||||||
|
// Check length and valid characters
|
||||||
|
if (!validChars.test(password)) return false;
|
||||||
|
|
||||||
|
// Count how many patterns are satisfied
|
||||||
|
const matchCount = patterns.filter((pattern) => pattern.test(password)).length;
|
||||||
|
|
||||||
|
// Must satisfy at least 2 patterns
|
||||||
|
return matchCount >= 2;
|
||||||
|
};
|
||||||
|
|||||||
@@ -0,0 +1,9 @@
|
|||||||
|
import { GET, POST, PUT } from '@/web/common/api/request';
|
||||||
|
import type { PaginationProps, PaginationResponse } from '@fastgpt/web/common/fetch/type';
|
||||||
|
import type { OperationListItemType } from '@fastgpt/global/support/operationLog/type';
|
||||||
|
|
||||||
|
export const getOperationLogs = (props: PaginationProps<PaginationProps>) =>
|
||||||
|
POST<PaginationResponse<OperationListItemType>>(
|
||||||
|
`/proApi/support/user/team/operationLog/list`,
|
||||||
|
props
|
||||||
|
);
|
||||||
57
projects/app/test/api/core/app/create.test.ts
Normal file
57
projects/app/test/api/core/app/create.test.ts
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
import * as createapi from '@/pages/api/core/app/create';
|
||||||
|
import { AppErrEnum } from '@fastgpt/global/common/error/code/app';
|
||||||
|
import { AppTypeEnum } from '@fastgpt/global/core/app/constants';
|
||||||
|
import { TeamAppCreatePermissionVal } from '@fastgpt/global/support/permission/user/constant';
|
||||||
|
import { MongoResourcePermission } from '@fastgpt/service/support/permission/schema';
|
||||||
|
import { getFakeUsers } from '@test/datas/users';
|
||||||
|
import { Call } from '@test/utils/request';
|
||||||
|
import { expect, it, describe } from 'vitest';
|
||||||
|
|
||||||
|
describe('create api', () => {
|
||||||
|
it('should return 200 when create app success', async () => {
|
||||||
|
const users = await getFakeUsers(2);
|
||||||
|
await MongoResourcePermission.create({
|
||||||
|
resourceType: 'team',
|
||||||
|
teamId: users.members[0].teamId,
|
||||||
|
resourceId: null,
|
||||||
|
tmbId: users.members[0].tmbId,
|
||||||
|
permission: TeamAppCreatePermissionVal
|
||||||
|
});
|
||||||
|
const res = await Call<createapi.CreateAppBody, {}, {}>(createapi.default, {
|
||||||
|
auth: users.members[0],
|
||||||
|
body: {
|
||||||
|
modules: [],
|
||||||
|
name: 'testfolder',
|
||||||
|
type: AppTypeEnum.folder
|
||||||
|
}
|
||||||
|
});
|
||||||
|
expect(res.error).toBeUndefined();
|
||||||
|
expect(res.code).toBe(200);
|
||||||
|
const folderId = res.data as string;
|
||||||
|
|
||||||
|
const res2 = await Call<createapi.CreateAppBody, {}, {}>(createapi.default, {
|
||||||
|
auth: users.members[0],
|
||||||
|
body: {
|
||||||
|
modules: [],
|
||||||
|
name: 'testapp',
|
||||||
|
type: AppTypeEnum.simple,
|
||||||
|
parentId: String(folderId)
|
||||||
|
}
|
||||||
|
});
|
||||||
|
expect(res2.error).toBeUndefined();
|
||||||
|
expect(res2.code).toBe(200);
|
||||||
|
expect(res2.data).toBeDefined();
|
||||||
|
|
||||||
|
const res3 = await Call<createapi.CreateAppBody, {}, {}>(createapi.default, {
|
||||||
|
auth: users.members[1],
|
||||||
|
body: {
|
||||||
|
modules: [],
|
||||||
|
name: 'testapp',
|
||||||
|
type: AppTypeEnum.simple,
|
||||||
|
parentId: String(folderId)
|
||||||
|
}
|
||||||
|
});
|
||||||
|
expect(res3.error).toBe(AppErrEnum.unAuthApp);
|
||||||
|
expect(res3.code).toBe(500);
|
||||||
|
});
|
||||||
|
});
|
||||||
54
projects/app/test/api/core/dataset/create.test.ts
Normal file
54
projects/app/test/api/core/dataset/create.test.ts
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
import * as createapi from '@/pages/api/core/dataset/create';
|
||||||
|
import { DatasetTypeEnum } from '@fastgpt/global/core/dataset/constants';
|
||||||
|
import { TeamDatasetCreatePermissionVal } from '@fastgpt/global/support/permission/user/constant';
|
||||||
|
import { MongoResourcePermission } from '@fastgpt/service/support/permission/schema';
|
||||||
|
import { getFakeUsers } from '@test/datas/users';
|
||||||
|
import { Call } from '@test/utils/request';
|
||||||
|
import { vi, describe, it, expect } from 'vitest';
|
||||||
|
|
||||||
|
describe('create dataset', () => {
|
||||||
|
it('should return 200 when create dataset success', async () => {
|
||||||
|
const users = await getFakeUsers(2);
|
||||||
|
await MongoResourcePermission.create({
|
||||||
|
resourceType: 'team',
|
||||||
|
teamId: users.members[0].teamId,
|
||||||
|
resourceId: null,
|
||||||
|
tmbId: users.members[0].tmbId,
|
||||||
|
permission: TeamDatasetCreatePermissionVal
|
||||||
|
});
|
||||||
|
const res = await Call<
|
||||||
|
createapi.DatasetCreateBody,
|
||||||
|
createapi.DatasetCreateQuery,
|
||||||
|
createapi.DatasetCreateResponse
|
||||||
|
>(createapi.default, {
|
||||||
|
auth: users.members[0],
|
||||||
|
body: {
|
||||||
|
name: 'folder',
|
||||||
|
intro: 'intro',
|
||||||
|
avatar: 'avatar',
|
||||||
|
type: DatasetTypeEnum.folder
|
||||||
|
}
|
||||||
|
});
|
||||||
|
expect(res.error).toBeUndefined();
|
||||||
|
expect(res.code).toBe(200);
|
||||||
|
const folderId = res.data as string;
|
||||||
|
|
||||||
|
const res2 = await Call<
|
||||||
|
createapi.DatasetCreateBody,
|
||||||
|
createapi.DatasetCreateQuery,
|
||||||
|
createapi.DatasetCreateResponse
|
||||||
|
>(createapi.default, {
|
||||||
|
auth: users.members[0],
|
||||||
|
body: {
|
||||||
|
name: 'test',
|
||||||
|
intro: 'intro',
|
||||||
|
avatar: 'avatar',
|
||||||
|
type: DatasetTypeEnum.dataset,
|
||||||
|
parentId: folderId
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(res2.error).toBeUndefined();
|
||||||
|
expect(res2.code).toBe(200);
|
||||||
|
});
|
||||||
|
});
|
||||||
64
projects/app/test/api/support/openapi/create.test.ts
Normal file
64
projects/app/test/api/support/openapi/create.test.ts
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
import { EditApiKeyProps } from '@/global/support/openapi/api';
|
||||||
|
import * as createapi from '@/pages/api/support/openapi/create';
|
||||||
|
import { DatasetTypeEnum } from '@fastgpt/global/core/dataset/constants';
|
||||||
|
import { ManagePermissionVal } from '@fastgpt/global/support/permission/constant';
|
||||||
|
import {
|
||||||
|
TeamApikeyCreatePermissionVal,
|
||||||
|
TeamDatasetCreatePermissionVal
|
||||||
|
} from '@fastgpt/global/support/permission/user/constant';
|
||||||
|
import { MongoApp } from '@fastgpt/service/core/app/schema';
|
||||||
|
import { MongoResourcePermission } from '@fastgpt/service/support/permission/schema';
|
||||||
|
import { getFakeUsers } from '@test/datas/users';
|
||||||
|
import { Call } from '@test/utils/request';
|
||||||
|
import { describe, it, expect } from 'vitest';
|
||||||
|
|
||||||
|
describe('create dataset', () => {
|
||||||
|
it('should return 200 when create dataset success', async () => {
|
||||||
|
const users = await getFakeUsers(2);
|
||||||
|
await MongoResourcePermission.create({
|
||||||
|
resourceType: 'team',
|
||||||
|
teamId: users.members[0].teamId,
|
||||||
|
resourceId: null,
|
||||||
|
tmbId: users.members[0].tmbId,
|
||||||
|
permission: TeamApikeyCreatePermissionVal
|
||||||
|
});
|
||||||
|
const res = await Call<EditApiKeyProps>(createapi.default, {
|
||||||
|
auth: users.members[0],
|
||||||
|
body: {
|
||||||
|
name: 'test',
|
||||||
|
limit: {
|
||||||
|
maxUsagePoints: 1000
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
expect(res.error).toBeUndefined();
|
||||||
|
expect(res.code).toBe(200);
|
||||||
|
|
||||||
|
await MongoResourcePermission.create({
|
||||||
|
resourceType: 'app',
|
||||||
|
teamId: users.members[1].teamId,
|
||||||
|
resourceId: null,
|
||||||
|
tmbId: users.members[1].tmbId,
|
||||||
|
permission: ManagePermissionVal
|
||||||
|
});
|
||||||
|
|
||||||
|
const app = await MongoApp.create({
|
||||||
|
name: 'a',
|
||||||
|
type: 'simple',
|
||||||
|
tmbId: users.members[1].tmbId,
|
||||||
|
teamId: users.members[1].teamId
|
||||||
|
});
|
||||||
|
const res2 = await Call<EditApiKeyProps>(createapi.default, {
|
||||||
|
auth: users.members[1],
|
||||||
|
body: {
|
||||||
|
appId: app._id,
|
||||||
|
name: 'test',
|
||||||
|
limit: {
|
||||||
|
maxUsagePoints: 1000
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
expect(res2.error).toBeUndefined();
|
||||||
|
expect(res2.code).toBe(200);
|
||||||
|
});
|
||||||
|
});
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user