Compare commits

..

18 Commits

Author SHA1 Message Date
Archer
c5db894e3a update doc (#4460)
* update preview action

* update doc

* remove

* update

* schema
2025-04-07 17:12:53 +08:00
archer
4fc96f6534 preview doc action
add docs preview permission

update preview action

udpate action
2025-04-07 13:57:54 +08:00
Archer
7ee616515d fix: ts (#4458) 2025-04-07 10:55:53 +08:00
archer
4207ecaaaa action 2025-04-07 10:29:19 +08:00
heheer
32ae14f281 fix external var ui (#4444) 2025-04-07 09:55:15 +08:00
archer
9670cba607 Update doc 2025-04-07 09:55:15 +08:00
archer
95d5c01db1 update doc 2025-04-07 09:55:14 +08:00
Archer
915569fe79 Test mongo log (#4443)
* feat: mongodb-log (#4426)

* perf: mongo log

* feat: completions stop reasoner

* mongo db log

---------

Co-authored-by: Finley Ge <32237950+FinleyGe@users.noreply.github.com>
2025-04-07 09:55:14 +08:00
archer
252ad8a611 package 2025-04-07 09:55:14 +08:00
Archer
85ce23869d Test completion v2 (#4438)
* add v2 completions (#4364)

* add v2 completions

* completion config

* config version

* fix

* frontend

* doc

* fix

* fix: completions v2 api

---------

Co-authored-by: heheer <heheer@sealos.io>
2025-04-07 09:55:13 +08:00
Archer
e4c4941a50 perf: mobile voice input (#4437)
* update:Mobile voice interaction (#4362)

* Add files via upload

* Add files via upload

* Update ollama.md

* Update ollama.md

* Add files via upload

* Update useSpeech.ts

* Update ChatInput.tsx

* Update useSpeech.ts

* Update ChatInput.tsx

* Update useSpeech.ts

* Update constants.ts

* Add files via upload

* Update ChatInput.tsx

* Update useSpeech.ts

* Update useSpeech.ts

* Update useSpeech.ts

* Update ChatInput.tsx

* Add files via upload

* Update common.json

* Update VoiceInput.tsx

* Update ChatInput.tsx

* Update VoiceInput.tsx

* Update useSpeech.ts

* Update useSpeech.ts

* Update common.json

* Update common.json

* Update common.json

* Update VoiceInput.tsx

* Update VoiceInput.tsx

* Update ChatInput.tsx

* Update VoiceInput.tsx

* Update ChatInput.tsx

* Update VoiceInput.tsx

* Update ChatInput.tsx

* Update useSpeech.ts

* Update common.json

* Update chat.json

* Update common.json

* Update chat.json

* Update common.json

* Update chat.json

* Update VoiceInput.tsx

* Update ChatInput.tsx

* Update useSpeech.ts

* Update VoiceInput.tsx

* speech ui

* 优化语音输入组件,调整输入框显示逻辑,修复语音输入遮罩层样式,更新画布背景透明度,增强用户交互体验。 (#4435)

* perf: mobil voice input

---------

Co-authored-by: dreamer6680 <1468683855@qq.com>
2025-04-07 09:55:13 +08:00
Archer
c2e088cf39 Redis cache (#4436)
* perf: add Redis cache for vector counting (#4432)

* feat: cache

* perf: get cache key

---------

Co-authored-by: a.e. <49438478+I-Info@users.noreply.github.com>
2025-04-07 09:55:13 +08:00
archer
dc73f47486 feat: config chat file expired time 2025-04-07 09:55:13 +08:00
archer
2f9b83d924 perf: remove loading ui 2025-04-07 09:55:12 +08:00
Archer
9fe95da126 pro migration (#4388) (#4433)
* pro migration

* reuse customPdfParseType

Co-authored-by: gggaaallleee <91131304+gggaaallleee@users.noreply.github.com>
2025-04-07 09:55:12 +08:00
Archer
d171b2d3d8 website sync feature (#4429)
* perf: introduce BullMQ for website sync (#4403)

* perf: introduce BullMQ for website sync

* feat: new redis module

* fix: remove graceful shutdown

* perf: improve UI in dataset detail

- Updated the "change" icon SVG file.
- Modified i18n strings.
- Added new i18n string "immediate_sync".
- Improved UI in dataset detail page, including button icons and
background colors.

* refactor: Add chunkSettings to DatasetSchema

* perf: website sync ux

* env template

* fix: clean up website dataset when updating chunk settings (#4420)

* perf: check setting updated

* perf: worker currency

* feat: init script for website sync refactor (#4425)

* website feature doc

---------

Co-authored-by: a.e. <49438478+I-Info@users.noreply.github.com>
2025-04-07 09:55:11 +08:00
archer
e54fe1eed6 doc 2025-04-07 09:55:10 +08:00
Archer
27332743c7 Training status (#4424)
* dataset data training state (#4311)

* dataset data training state

* fix

* fix ts

* fix

* fix api format

* fix

* fix

* perf: count training

* format

* fix: dataset training state (#4417)

* fix

* add test

* fix

* fix

* fix test

* fix test

* perf: training count

* count

* loading status

---------

Co-authored-by: heheer <heheer@sealos.io>
2025-04-07 09:55:07 +08:00
161 changed files with 1833 additions and 3327 deletions

View File

@@ -1,4 +1,4 @@
yangchuansheng/fastgpt-imgs:
- source: docSite/assets/imgs/
dest: imgs/
deleteOrphaned: true
deleteOrphaned: true

View File

@@ -1,4 +1,4 @@
name: Deploy doc image to cf
name: Deploy doc image to vercel
on:
workflow_dispatch:
@@ -63,6 +63,18 @@ jobs:
- name: Build
run: cd docSite && hugo mod get -u github.com/colinwilson/lotusdocs@6d0568e && hugo -v --minify
# Step 5 - Push our generated site to Vercel
- name: Deploy to Vercel
uses: amondnet/vercel-action@v25
id: vercel-action
with:
vercel-token: ${{ secrets.VERCEL_TOKEN }} # Required
vercel-org-id: ${{ secrets.VERCEL_ORG_ID }} #Required
vercel-project-id: ${{ secrets.VERCEL_PROJECT_ID }} #Required
github-comment: false
vercel-args: '--prod --local-config ../vercel.json' # Optional
working-directory: docSite/public
- name: Deploy to GitHub Pages
uses: peaceiris/actions-gh-pages@v4
if: github.ref == 'refs/heads/main'

View File

@@ -1,7 +1,7 @@
name: Preview FastGPT docs
on:
pull_request_target:
pull_request:
paths:
- 'docSite/**'
workflow_dispatch:
@@ -50,6 +50,10 @@ jobs:
- 'docSite/content/docs/**'
base: main
- name: Add cdn for images
run: |
sed -i "s#\](/imgs/#\](https://cdn.jsdelivr.net/gh/yangchuansheng/fastgpt-imgs@main/imgs/#g" $(grep -rl "\](/imgs/" docSite/content/zh-cn/docs)
# Step 3 - Install Hugo (specific version)
- name: Install Hugo
uses: peaceiris/actions-hugo@v2
@@ -61,6 +65,9 @@ jobs:
- name: Build
run: cd docSite && hugo mod get -u github.com/colinwilson/lotusdocs@6d0568e && hugo -v --minify
- name: Test
run: ls ./docSite/public
# Step 5 - Push our generated site to Cloudflare
- name: Deploy to Cloudflare Pages
id: deploy

View File

@@ -1,14 +1,12 @@
name: Build FastGPT images
on:
workflow_dispatch:
push:
paths:
- "projects/app/**"
- "packages/**"
- 'projects/app/**'
- 'packages/**'
tags:
- "v*"
- 'v*'
jobs:
build-fastgpt-images:
permissions:
@@ -16,156 +14,260 @@ jobs:
contents: read
attestations: write
id-token: write
strategy:
matrix:
sub_routes:
- repo: fastgpt
base_url: ""
- repo: fastgpt-sub-route
base_url: "/fastai"
- repo: fastgpt-sub-route-gchat
base_url: "/gchat"
archs:
- arch: amd64
- arch: arm64
runs-on: ubuntu-24.04-arm
runs-on: ${{ matrix.archs.runs-on || 'ubuntu-24.04' }}
runs-on: ubuntu-20.04
steps:
# install env
- name: Checkout
uses: actions/checkout@v4
uses: actions/checkout@v3
with:
fetch-depth: 1
- name: Install Dependencies
run: |
sudo apt update && sudo apt install -y nodejs npm
- name: Set up QEMU (optional)
uses: docker/setup-qemu-action@v2
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
uses: docker/setup-buildx-action@v2
with:
driver-opts: network=host
- name: Cache Docker layers
uses: actions/cache@v4
with:
path: /tmp/.buildx-cache
key: ${{ runner.os }}-${{ matrix.sub_routes.repo }}-buildx-${{ github.sha }}
key: ${{ runner.os }}-buildx-${{ github.sha }}
restore-keys: |
${{ runner.os }}-${{ matrix.sub_routes.repo }}-buildx-
${{ runner.os }}-buildx-
# login docker
- name: Login to GitHub Container Registry
uses: docker/login-action@v3
uses: docker/login-action@v2
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Login to Ali Hub
uses: docker/login-action@v3
uses: docker/login-action@v2
with:
registry: registry.cn-hangzhou.aliyuncs.com
username: ${{ secrets.ALI_HUB_USERNAME }}
password: ${{ secrets.ALI_HUB_PASSWORD }}
- name: Login to Docker Hub
uses: docker/login-action@v3
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKER_HUB_NAME }}
password: ${{ secrets.DOCKER_HUB_PASSWORD }}
- name: Build for ${{ matrix.archs.arch }}
id: build
uses: docker/build-push-action@v6
with:
context: .
file: projects/app/Dockerfile
platforms: linux/${{ matrix.archs.arch }}
build-args: |
${{ matrix.sub_routes.base_url && format('base_url={0}', matrix.sub_routes.base_url) || '' }}
labels: |
org.opencontainers.image.source=https://github.com/${{ github.repository_owner }}/${{ matrix.sub_routes.repo }}
org.opencontainers.image.description=${{ matrix.sub_routes.repo }} image
outputs: type=image,"name=ghcr.io/${{ github.repository_owner }}/${{ matrix.sub_routes.repo }},${{ secrets.ALI_IMAGE_NAME }}/${{ matrix.sub_routes.repo }},${{ secrets.DOCKER_IMAGE_NAME }}/${{ matrix.sub_routes.repo }}",push-by-digest=true,push=true
cache-from: type=local,src=/tmp/.buildx-cache
cache-to: type=local,dest=/tmp/.buildx-cache
- name: Export digest
# Set tag
- name: Set image name and tag
run: |
mkdir -p ${{ runner.temp }}/digests/${{ matrix.sub_routes.repo }}
digest="${{ steps.build.outputs.digest }}"
touch "${{ runner.temp }}/digests/${{ matrix.sub_routes.repo }}/${digest#sha256:}"
if [[ "${{ github.ref_name }}" == "main" ]]; then
echo "Git_Tag=ghcr.io/${{ github.repository_owner }}/fastgpt:latest" >> $GITHUB_ENV
echo "Git_Latest=ghcr.io/${{ github.repository_owner }}/fastgpt:latest" >> $GITHUB_ENV
echo "Ali_Tag=${{ secrets.ALI_IMAGE_NAME }}/fastgpt:latest" >> $GITHUB_ENV
echo "Ali_Latest=${{ secrets.ALI_IMAGE_NAME }}/fastgpt:latest" >> $GITHUB_ENV
echo "Docker_Hub_Tag=${{ secrets.DOCKER_IMAGE_NAME }}/fastgpt:latest" >> $GITHUB_ENV
echo "Docker_Hub_Latest=${{ secrets.DOCKER_IMAGE_NAME }}/fastgpt:latest" >> $GITHUB_ENV
else
echo "Git_Tag=ghcr.io/${{ github.repository_owner }}/fastgpt:${{ github.ref_name }}" >> $GITHUB_ENV
echo "Git_Latest=ghcr.io/${{ github.repository_owner }}/fastgpt:latest" >> $GITHUB_ENV
echo "Ali_Tag=${{ secrets.ALI_IMAGE_NAME }}/fastgpt:${{ github.ref_name }}" >> $GITHUB_ENV
echo "Ali_Latest=${{ secrets.ALI_IMAGE_NAME }}/fastgpt:latest" >> $GITHUB_ENV
echo "Docker_Hub_Tag=${{ secrets.DOCKER_IMAGE_NAME }}/fastgpt:${{ github.ref_name }}" >> $GITHUB_ENV
echo "Docker_Hub_Latest=${{ secrets.DOCKER_IMAGE_NAME }}/fastgpt:latest" >> $GITHUB_ENV
fi
- name: Upload digest
uses: actions/upload-artifact@v4
with:
name: digests-${{ matrix.sub_routes.repo }}-${{ github.sha }}-${{ matrix.archs.arch }}
path: ${{ runner.temp }}/digests/${{ matrix.sub_routes.repo }}/*
if-no-files-found: error
retention-days: 1
release-fastgpt-images:
- name: Build and publish image for main branch or tag push event
env:
DOCKER_REPO_TAGGED: ${{ env.DOCKER_REPO_TAGGED }}
run: |
docker buildx build \
-f projects/app/Dockerfile \
--platform linux/amd64,linux/arm64 \
--label "org.opencontainers.image.source=https://github.com/${{ github.repository_owner }}/FastGPT" \
--label "org.opencontainers.image.description=fastgpt image" \
--push \
--cache-from=type=local,src=/tmp/.buildx-cache \
--cache-to=type=local,dest=/tmp/.buildx-cache \
-t ${Git_Tag} \
-t ${Git_Latest} \
-t ${Ali_Tag} \
-t ${Ali_Latest} \
-t ${Docker_Hub_Tag} \
-t ${Docker_Hub_Latest} \
.
build-fastgpt-images-sub-route:
permissions:
packages: write
contents: read
attestations: write
id-token: write
needs: build-fastgpt-images
strategy:
matrix:
sub_routes:
- repo: fastgpt
- repo: fastgpt-sub-route
- repo: fastgpt-sub-route-gchat
runs-on: ubuntu-24.04
runs-on: ubuntu-20.04
steps:
# install env
- name: Checkout
uses: actions/checkout@v3
with:
fetch-depth: 1
- name: Install Dependencies
run: |
sudo apt update && sudo apt install -y nodejs npm
- name: Set up QEMU (optional)
uses: docker/setup-qemu-action@v2
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
with:
driver-opts: network=host
- name: Cache Docker layers
uses: actions/cache@v4
with:
path: /tmp/.buildx-cache
key: ${{ runner.os }}-buildx-${{ github.sha }}
restore-keys: |
${{ runner.os }}-buildx-
# login docker
- name: Login to GitHub Container Registry
uses: docker/login-action@v3
uses: docker/login-action@v2
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Login to Ali Hub
uses: docker/login-action@v3
uses: docker/login-action@v2
with:
registry: registry.cn-hangzhou.aliyuncs.com
username: ${{ secrets.ALI_HUB_USERNAME }}
password: ${{ secrets.ALI_HUB_PASSWORD }}
- name: Login to Docker Hub
uses: docker/login-action@v3
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKER_HUB_NAME }}
password: ${{ secrets.DOCKER_HUB_PASSWORD }}
- name: Download digests
uses: actions/download-artifact@v4
with:
path: ${{ runner.temp }}/digests
pattern: digests-${{ matrix.sub_routes.repo }}-${{ github.sha }}-*
merge-multiple: true
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
# Set tag
- name: Set image name and tag
run: |
if [[ "${{ github.ref_name }}" == "main" ]]; then
echo "Git_Tag=ghcr.io/${{ github.repository_owner }}/${{ matrix.sub_routes.repo }}:latest" >> $GITHUB_ENV
echo "Git_Latest=ghcr.io/${{ github.repository_owner }}/${{ matrix.sub_routes.repo }}:latest" >> $GITHUB_ENV
echo "Ali_Tag=${{ secrets.ALI_IMAGE_NAME }}/${{ matrix.sub_routes.repo }}:latest" >> $GITHUB_ENV
echo "Ali_Latest=${{ secrets.ALI_IMAGE_NAME }}/${{ matrix.sub_routes.repo }}:latest" >> $GITHUB_ENV
echo "Docker_Hub_Tag=${{ secrets.DOCKER_IMAGE_NAME }}/${{ matrix.sub_routes.repo }}:latest" >> $GITHUB_ENV
echo "Docker_Hub_Latest=${{ secrets.DOCKER_IMAGE_NAME }}/${{ matrix.sub_routes.repo }}:latest" >> $GITHUB_ENV
echo "Git_Tag=ghcr.io/${{ github.repository_owner }}/fastgpt-sub-route:latest" >> $GITHUB_ENV
echo "Git_Latest=ghcr.io/${{ github.repository_owner }}/fastgpt-sub-route:latest" >> $GITHUB_ENV
echo "Ali_Tag=${{ secrets.ALI_IMAGE_NAME }}/fastgpt-sub-route:latest" >> $GITHUB_ENV
echo "Ali_Latest=${{ secrets.ALI_IMAGE_NAME }}/fastgpt-sub-route:latest" >> $GITHUB_ENV
echo "Docker_Hub_Tag=${{ secrets.DOCKER_IMAGE_NAME }}/fastgpt-sub-route:latest" >> $GITHUB_ENV
echo "Docker_Hub_Latest=${{ secrets.DOCKER_IMAGE_NAME }}/fastgpt-sub-route:latest" >> $GITHUB_ENV
else
echo "Git_Tag=ghcr.io/${{ github.repository_owner }}/${{ matrix.sub_routes.repo }}:${{ github.ref_name }}" >> $GITHUB_ENV
echo "Git_Latest=ghcr.io/${{ github.repository_owner }}/${{ matrix.sub_routes.repo }}:latest" >> $GITHUB_ENV
echo "Ali_Tag=${{ secrets.ALI_IMAGE_NAME }}/${{ matrix.sub_routes.repo }}:${{ github.ref_name }}" >> $GITHUB_ENV
echo "Ali_Latest=${{ secrets.ALI_IMAGE_NAME }}/${{ matrix.sub_routes.repo }}:latest" >> $GITHUB_ENV
echo "Docker_Hub_Tag=${{ secrets.DOCKER_IMAGE_NAME }}/${{ matrix.sub_routes.repo }}:${{ github.ref_name }}" >> $GITHUB_ENV
echo "Docker_Hub_Latest=${{ secrets.DOCKER_IMAGE_NAME }}/${{ matrix.sub_routes.repo }}:latest" >> $GITHUB_ENV
echo "Git_Tag=ghcr.io/${{ github.repository_owner }}/fastgpt-sub-route:${{ github.ref_name }}" >> $GITHUB_ENV
echo "Git_Latest=ghcr.io/${{ github.repository_owner }}/fastgpt-sub-route:latest" >> $GITHUB_ENV
echo "Ali_Tag=${{ secrets.ALI_IMAGE_NAME }}/fastgpt-sub-route:${{ github.ref_name }}" >> $GITHUB_ENV
echo "Ali_Latest=${{ secrets.ALI_IMAGE_NAME }}/fastgpt-sub-route:latest" >> $GITHUB_ENV
echo "Docker_Hub_Tag=${{ secrets.DOCKER_IMAGE_NAME }}/fastgpt-sub-route:${{ github.ref_name }}" >> $GITHUB_ENV
echo "Docker_Hub_Latest=${{ secrets.DOCKER_IMAGE_NAME }}/fastgpt-sub-route:latest" >> $GITHUB_ENV
fi
- name: Create manifest list and push
working-directory: ${{ runner.temp }}/digests
- name: Build and publish image for main branch or tag push event
env:
DOCKER_REPO_TAGGED: ${{ env.DOCKER_REPO_TAGGED }}
run: |
TAGS="$(echo -e "${Git_Tag}\n${Git_Latest}\n${Ali_Tag}\n${Ali_Latest}\n${Docker_Hub_Tag}\n${Docker_Hub_Latest}")"
for TAG in $TAGS; do
docker buildx imagetools create -t $TAG \
$(printf 'ghcr.io/${{ github.repository_owner }}/${{ matrix.sub_routes.repo }}@sha256:%s ' *)
sleep 5
done
docker buildx build \
-f projects/app/Dockerfile \
--platform linux/amd64,linux/arm64 \
--build-arg base_url=/fastai \
--label "org.opencontainers.image.source=https://github.com/${{ github.repository_owner }}/FastGPT" \
--label "org.opencontainers.image.description=fastgpt image" \
--push \
--cache-from=type=local,src=/tmp/.buildx-cache \
--cache-to=type=local,dest=/tmp/.buildx-cache \
-t ${Git_Tag} \
-t ${Git_Latest} \
-t ${Ali_Tag} \
-t ${Ali_Latest} \
-t ${Docker_Hub_Tag} \
-t ${Docker_Hub_Latest} \
.
build-fastgpt-images-sub-route-gchat:
permissions:
packages: write
contents: read
attestations: write
id-token: write
runs-on: ubuntu-20.04
steps:
# install env
- name: Checkout
uses: actions/checkout@v3
with:
fetch-depth: 1
- name: Install Dependencies
run: |
sudo apt update && sudo apt install -y nodejs npm
- name: Set up QEMU (optional)
uses: docker/setup-qemu-action@v2
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
with:
driver-opts: network=host
- name: Cache Docker layers
uses: actions/cache@v4
with:
path: /tmp/.buildx-cache
key: ${{ runner.os }}-buildx-${{ github.sha }}
restore-keys: |
${{ runner.os }}-buildx-
# login docker
- name: Login to GitHub Container Registry
uses: docker/login-action@v2
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Login to Ali Hub
uses: docker/login-action@v2
with:
registry: registry.cn-hangzhou.aliyuncs.com
username: ${{ secrets.ALI_HUB_USERNAME }}
password: ${{ secrets.ALI_HUB_PASSWORD }}
- name: Login to Docker Hub
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKER_HUB_NAME }}
password: ${{ secrets.DOCKER_HUB_PASSWORD }}
# Set tag
- name: Set image name and tag
run: |
if [[ "${{ github.ref_name }}" == "main" ]]; then
echo "Git_Tag=ghcr.io/${{ github.repository_owner }}/fastgpt-sub-route-gchat:latest" >> $GITHUB_ENV
echo "Git_Latest=ghcr.io/${{ github.repository_owner }}/fastgpt-sub-route-gchat:latest" >> $GITHUB_ENV
echo "Ali_Tag=${{ secrets.ALI_IMAGE_NAME }}/fastgpt-sub-route-gchat:latest" >> $GITHUB_ENV
echo "Ali_Latest=${{ secrets.ALI_IMAGE_NAME }}/fastgpt-sub-route-gchat:latest" >> $GITHUB_ENV
echo "Docker_Hub_Tag=${{ secrets.DOCKER_IMAGE_NAME }}/fastgpt-sub-route-gchat:latest" >> $GITHUB_ENV
echo "Docker_Hub_Latest=${{ secrets.DOCKER_IMAGE_NAME }}/fastgpt-sub-route-gchat:latest" >> $GITHUB_ENV
else
echo "Git_Tag=ghcr.io/${{ github.repository_owner }}/fastgpt-sub-route-gchat:${{ github.ref_name }}" >> $GITHUB_ENV
echo "Git_Latest=ghcr.io/${{ github.repository_owner }}/fastgpt-sub-route-gchat:latest" >> $GITHUB_ENV
echo "Ali_Tag=${{ secrets.ALI_IMAGE_NAME }}/fastgpt-sub-route-gchat:${{ github.ref_name }}" >> $GITHUB_ENV
echo "Ali_Latest=${{ secrets.ALI_IMAGE_NAME }}/fastgpt-sub-route-gchat:latest" >> $GITHUB_ENV
echo "Docker_Hub_Tag=${{ secrets.DOCKER_IMAGE_NAME }}/fastgpt-sub-route-gchat:${{ github.ref_name }}" >> $GITHUB_ENV
echo "Docker_Hub_Latest=${{ secrets.DOCKER_IMAGE_NAME }}/fastgpt-sub-route-gchat:latest" >> $GITHUB_ENV
fi
- name: Build and publish image for main branch or tag push event
env:
DOCKER_REPO_TAGGED: ${{ env.DOCKER_REPO_TAGGED }}
run: |
docker buildx build \
-f projects/app/Dockerfile \
--platform linux/amd64,linux/arm64 \
--build-arg base_url=/gchat \
--label "org.opencontainers.image.source=https://github.com/${{ github.repository_owner }}/FastGPT" \
--label "org.opencontainers.image.description=fastgpt-sub-route-gchat image" \
--push \
--cache-from=type=local,src=/tmp/.buildx-cache \
--cache-to=type=local,dest=/tmp/.buildx-cache \
-t ${Git_Tag} \
-t ${Git_Latest} \
-t ${Ali_Tag} \
-t ${Ali_Latest} \
-t ${Docker_Hub_Tag} \
-t ${Docker_Hub_Latest} \
.

View File

@@ -15,9 +15,6 @@ jobs:
steps:
- 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
with:
version: 10

View File

@@ -13,115 +13,50 @@ jobs:
contents: read
attestations: write
id-token: write
strategy:
matrix:
include:
- arch: amd64
- arch: arm64
runs-on: ubuntu-24.04-arm
runs-on: ${{ matrix.runs-on || 'ubuntu-24.04' }}
runs-on: ubuntu-20.04
steps:
# install env
- name: Checkout
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Install Dependencies
run: |
sudo apt update && sudo apt install -y nodejs npm
- name: Set up QEMU (optional)
uses: docker/setup-qemu-action@v2
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
uses: docker/setup-buildx-action@v2
with:
driver-opts: network=host
- name: Cache Docker layers
uses: actions/cache@v4
with:
path: /tmp/.buildx-cache
key: ${{ runner.os }}-sandbox-buildx-${{ github.sha }}
key: ${{ runner.os }}-buildx-${{ github.sha }}
restore-keys: |
${{ runner.os }}-sandbox-buildx-
${{ runner.os }}-buildx-
# login docker
- name: Login to GitHub Container Registry
uses: docker/login-action@v3
uses: docker/login-action@v2
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Login to Ali Hub
uses: docker/login-action@v3
uses: docker/login-action@v2
with:
registry: registry.cn-hangzhou.aliyuncs.com
username: ${{ secrets.ALI_HUB_USERNAME }}
password: ${{ secrets.ALI_HUB_PASSWORD }}
- name: Login to Docker Hub
uses: docker/login-action@v3
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKER_HUB_NAME }}
password: ${{ secrets.DOCKER_HUB_PASSWORD }}
- name: Build for ${{ matrix.arch }}
id: build
uses: docker/build-push-action@v6
with:
context: .
file: projects/sandbox/Dockerfile
platforms: linux/${{ matrix.arch }}
labels: |
org.opencontainers.image.source=https://github.com/${{ github.repository_owner }}/fastgpt-sandbox
org.opencontainers.image.description=fastgpt-sandbox image
outputs: type=image,"name=ghcr.io/${{ github.repository_owner }}/fastgpt-sandbox,${{ secrets.ALI_IMAGE_NAME }}/fastgpt-sandbox,${{ secrets.DOCKER_IMAGE_NAME }}/fastgpt-sandbox",push-by-digest=true,push=true
cache-from: type=local,src=/tmp/.buildx-cache
cache-to: type=local,dest=/tmp/.buildx-cache
- name: Export digest
run: |
mkdir -p ${{ runner.temp }}/digests
digest="${{ steps.build.outputs.digest }}"
touch "${{ runner.temp }}/digests/${digest#sha256:}"
- name: Upload digest
uses: actions/upload-artifact@v4
with:
name: digests-fastgpt-sandbox-${{ github.sha }}-${{ matrix.arch }}
path: ${{ runner.temp }}/digests/*
if-no-files-found: error
retention-days: 1
release-fastgpt-sandbox-images:
permissions:
packages: write
contents: read
attestations: write
id-token: write
needs: build-fastgpt-sandbox-images
runs-on: ubuntu-24.04
steps:
- name: Login to GitHub Container Registry
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Login to Ali Hub
uses: docker/login-action@v3
with:
registry: registry.cn-hangzhou.aliyuncs.com
username: ${{ secrets.ALI_HUB_USERNAME }}
password: ${{ secrets.ALI_HUB_PASSWORD }}
- name: Login to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKER_HUB_NAME }}
password: ${{ secrets.DOCKER_HUB_PASSWORD }}
- name: Download digests
uses: actions/download-artifact@v4
with:
path: ${{ runner.temp }}/digests
pattern: digests-fastgpt-sandbox-${{ github.sha }}-*
merge-multiple: true
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
# Set tag
- name: Set image name and tag
run: |
if [[ "${{ github.ref_name }}" == "main" ]]; then
@@ -140,12 +75,27 @@ jobs:
echo "Docker_Hub_Latest=${{ secrets.DOCKER_IMAGE_NAME }}/fastgpt-sandbox:latest" >> $GITHUB_ENV
fi
- name: Create manifest list and push
working-directory: ${{ runner.temp }}/digests
- name: Build and publish image for main branch or tag push event
env:
Git_Tag: ${{ env.Git_Tag }}
Git_Latest: ${{ env.Git_Latest }}
Ali_Tag: ${{ env.Ali_Tag }}
Ali_Latest: ${{ env.Ali_Latest }}
Docker_Hub_Tag: ${{ env.Docker_Hub_Tag }}
Docker_Hub_Latest: ${{ env.Docker_Hub_Latest }}
run: |
TAGS="$(echo -e "${Git_Tag}\n${Git_Latest}\n${Ali_Tag}\n${Ali_Latest}\n${Docker_Hub_Tag}\n${Docker_Hub_Latest}")"
for TAG in $TAGS; do
docker buildx imagetools create -t $TAG \
$(printf 'ghcr.io/${{ github.repository_owner }}/fastgpt-sandbox@sha256:%s ' *)
sleep 5
done
docker buildx build \
-f projects/sandbox/Dockerfile \
--platform linux/amd64,linux/arm64 \
--label "org.opencontainers.image.source=https://github.com/${{ github.repository_owner }}/fastgpt-sandbox" \
--label "org.opencontainers.image.description=fastgpt-sandbox image" \
--push \
--cache-from=type=local,src=/tmp/.buildx-cache \
--cache-to=type=local,dest=/tmp/.buildx-cache \
-t ${Git_Tag} \
-t ${Git_Latest} \
-t ${Ali_Tag} \
-t ${Ali_Latest} \
-t ${Docker_Hub_Tag} \
-t ${Docker_Hub_Latest} \
.

View File

@@ -10,7 +10,7 @@
<a href="./README_ja.md">日语</a>
</p>
FastGPT 是一个 AI Agent 构建平台,提供开箱即用的数据处理、模型调用等能力同时可以通过 Flow 可视化进行工作流编排,从而实现复杂的应用场景!
FastGPT 是一个基于 LLM 大语言模型的知识库问答系统,提供开箱即用的数据处理、模型调用等能力同时可以通过 Flow 可视化进行工作流编排,从而实现复杂的问答场景!
</div>

View File

@@ -126,15 +126,15 @@ services:
# fastgpt
sandbox:
container_name: sandbox
image: ghcr.io/labring/fastgpt-sandbox:v4.9.4 # git
# image: registry.cn-hangzhou.aliyuncs.com/fastgpt/fastgpt-sandbox:v4.9.4 # 阿里云
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.4 # git
# image: registry.cn-hangzhou.aliyuncs.com/fastgpt/fastgpt:v4.9.4 # 阿里云
image: ghcr.io/labring/fastgpt:v4.9.3 # git
# image: registry.cn-hangzhou.aliyuncs.com/fastgpt/fastgpt:v4.9.3 # 阿里云
ports:
- 3000:3000
networks:
@@ -184,8 +184,6 @@ services:
- ALLOWED_ORIGINS=
# 是否开启IP限制默认不开启
- USE_IP_LIMIT=false
# 对话文件过期天数
- CHAT_FILE_EXPIRE_TIME=7
volumes:
- ./config.json:/app/data/config.json

View File

@@ -1,202 +0,0 @@
# 数据库的默认账号和密码仅首次运行时设置有效
# 如果修改了账号密码,记得改数据库和项目连接参数,别只改一处~
# 该配置文件只是给快速启动,测试使用。正式使用,记得务必修改账号密码,以及调整合适的知识库参数,共享内存等。
# 如何无法访问 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:

View File

@@ -1,2 +0,0 @@
ALTER SYSTEM SET ob_vector_memory_limit_percentage = 30;

View File

@@ -85,15 +85,15 @@ services:
# fastgpt
sandbox:
container_name: sandbox
image: ghcr.io/labring/fastgpt-sandbox:v4.9.4 # git
# image: registry.cn-hangzhou.aliyuncs.com/fastgpt/fastgpt-sandbox:v4.9.4 # 阿里云
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.4 # git
# image: registry.cn-hangzhou.aliyuncs.com/fastgpt/fastgpt:v4.9.4 # 阿里云
image: ghcr.io/labring/fastgpt:v4.9.3 # git
# image: registry.cn-hangzhou.aliyuncs.com/fastgpt/fastgpt:v4.9.3 # 阿里云
ports:
- 3000:3000
networks:
@@ -142,8 +142,6 @@ services:
- ALLOWED_ORIGINS=
# 是否开启IP限制默认不开启
- USE_IP_LIMIT=false
# 对话文件过期天数
- CHAT_FILE_EXPIRE_TIME=7
volumes:
- ./config.json:/app/data/config.json

View File

@@ -66,15 +66,15 @@ services:
sandbox:
container_name: sandbox
image: ghcr.io/labring/fastgpt-sandbox:v4.9.4 # git
# image: registry.cn-hangzhou.aliyuncs.com/fastgpt/fastgpt-sandbox:v4.9.4 # 阿里云
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.4 # git
# image: registry.cn-hangzhou.aliyuncs.com/fastgpt/fastgpt:v4.9.4 # 阿里云
image: ghcr.io/labring/fastgpt:v4.9.3 # git
# image: registry.cn-hangzhou.aliyuncs.com/fastgpt/fastgpt:v4.9.3 # 阿里云
ports:
- 3000:3000
networks:
@@ -123,8 +123,6 @@ services:
- ALLOWED_ORIGINS=
# 是否开启IP限制默认不开启
- USE_IP_LIMIT=false
# 对话文件过期天数
- CHAT_FILE_EXPIRE_TIME=7
volumes:
- ./config.json:/app/data/config.json

View File

@@ -135,9 +135,6 @@ curl -O https://raw.githubusercontent.com/labring/FastGPT/main/projects/app/data
# pgvector 版本(测试推荐,简单快捷)
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 版本
# curl -o docker-compose.yml https://raw.githubusercontent.com/labring/FastGPT/main/deploy/docker/docker-compose-milvus.yml
# zilliz 版本
@@ -154,13 +151,6 @@ curl -o docker-compose.yml https://raw.githubusercontent.com/labring/FastGPT/mai
无需操作
{{< /markdownify >}}
{{< /tab >}}
{{< tab tabName="Oceanbase版本" >}}
{{< markdownify >}}
无需操作
{{< /markdownify >}}
{{< /tab >}}
{{< tab tabName="Milvus版本" >}}

View File

@@ -34,94 +34,6 @@ weight: 852
### 请求
{{< tabs tabTotal="3" >}}
{{< tab tabName="基础请求示例" >}}
{{< markdownify >}}
```bash
curl --location --request POST 'http://localhost:3000/api/v1/chat/completions' \
--header 'Authorization: Bearer fastgpt-xxxxxx' \
--header 'Content-Type: application/json' \
--data-raw '{
"chatId": "my_chatId",
"stream": false,
"detail": false,
"responseChatItemId": "my_responseChatItemId",
"variables": {
"uid": "asdfadsfasfd2323",
"name": "张三"
},
"messages": [
{
"role": "user",
"content": "导演是谁"
}
]
}'
```
{{< /markdownify >}}
{{< /tab >}}
{{< tab tabName="图片/文件请求示例" >}}
{{< markdownify >}}
*`messages`有部分区别,其他参数一致。
* 目前不支持上传文件,需上传到自己的对象存储中,获取对应的文件链接。
```bash
curl --location --request POST 'http://localhost:3000/api/v1/chat/completions' \
--header 'Authorization: Bearer fastgpt-xxxxxx' \
--header 'Content-Type: application/json' \
--data-raw '{
"chatId": "abcd",
"stream": false,
"messages": [
{
"role": "user",
"content": [
{
"type": "text",
"text": "导演是谁"
},
{
"type": "image_url",
"image_url": {
"url": "图片链接"
}
},
{
"type": "file_url",
"name": "文件名",
"url": "文档链接,支持 txt md html word pdf ppt csv excel"
}
]
}
]
}'
```
{{< /markdownify >}}
{{< /tab >}}
{{< tab tabName="参数说明" >}}
{{< markdownify >}}
{{% alert context="info" %}}
- headers.Authorization: Bearer {{apikey}}
- chatId: string | undefined 。
-`undefined` 时(不传入),不使用 FastGpt 提供的上下文功能,完全通过传入的 messages 构建上下文。
-`非空字符串`时,意味着使用 chatId 进行对话,自动从 FastGpt 数据库取历史记录,并使用 messages 数组最后一个内容作为用户问题,其余 message 会被忽略。请自行确保 chatId 唯一长度小于250通常可以是自己系统的对话框ID。
- messages: 结构与 [GPT接口](https://platform.openai.com/docs/api-reference/chat/object) chat模式一致。
- responseChatItemId: string | undefined 。如果传入,则会将该值作为本次对话的响应消息的 IDFastGPT 会自动将该 ID 存入数据库。请确保,在当前`chatId`下,`responseChatItemId`是唯一的。
- detail: 是否返回中间值(模块状态,响应的完整结果等),`stream模式`下会通过`event`进行区分,`非stream模式`结果保存在`responseData`中。
- variables: 模块变量,一个对象,会替换模块中,输入框内容里的`{{key}}`
{{% /alert %}}
{{< /markdownify >}}
{{< /tab >}}
{{< /tabs >}}
<!-- #### v2
v1,v2 接口请求参数一致,仅请求地址不一样。
@@ -216,7 +128,93 @@ curl --location --request POST 'http://localhost:3000/api/v2/chat/completions' \
#### v1
{{< tabs tabTotal="3" >}}
{{< tab tabName="基础请求示例" >}}
{{< markdownify >}}
```bash
curl --location --request POST 'http://localhost:3000/api/v1/chat/completions' \
--header 'Authorization: Bearer fastgpt-xxxxxx' \
--header 'Content-Type: application/json' \
--data-raw '{
"chatId": "my_chatId",
"stream": false,
"detail": false,
"responseChatItemId": "my_responseChatItemId",
"variables": {
"uid": "asdfadsfasfd2323",
"name": "张三"
},
"messages": [
{
"role": "user",
"content": "导演是谁"
}
]
}'
```
{{< /markdownify >}}
{{< /tab >}}
{{< tab tabName="图片/文件请求示例" >}}
{{< markdownify >}}
*`messages`有部分区别,其他参数一致。
* 目前不支持上传文件,需上传到自己的对象存储中,获取对应的文件链接。
```bash
curl --location --request POST 'http://localhost:3000/api/v1/chat/completions' \
--header 'Authorization: Bearer fastgpt-xxxxxx' \
--header 'Content-Type: application/json' \
--data-raw '{
"chatId": "abcd",
"stream": false,
"messages": [
{
"role": "user",
"content": [
{
"type": "text",
"text": "导演是谁"
},
{
"type": "image_url",
"image_url": {
"url": "图片链接"
}
},
{
"type": "file_url",
"name": "文件名",
"url": "文档链接,支持 txt md html word pdf ppt csv excel"
}
]
}
]
}'
```
{{< /markdownify >}}
{{< /tab >}}
{{< tab tabName="参数说明" >}}
{{< markdownify >}}
{{% alert context="info" %}}
- headers.Authorization: Bearer {{apikey}}
- chatId: string | undefined 。
-`undefined` 时(不传入),不使用 FastGpt 提供的上下文功能,完全通过传入的 messages 构建上下文。
-`非空字符串`时,意味着使用 chatId 进行对话,自动从 FastGpt 数据库取历史记录,并使用 messages 数组最后一个内容作为用户问题,其余 message 会被忽略。请自行确保 chatId 唯一长度小于250通常可以是自己系统的对话框ID。
- messages: 结构与 [GPT接口](https://platform.openai.com/docs/api-reference/chat/object) chat模式一致。
- responseChatItemId: string | undefined 。如果传入,则会将该值作为本次对话的响应消息的 IDFastGPT 会自动将该 ID 存入数据库。请确保,在当前`chatId`下,`responseChatItemId`是唯一的。
- detail: 是否返回中间值(模块状态,响应的完整结果等),`stream模式`下会通过`event`进行区分,`非stream模式`结果保存在`responseData`中。
- variables: 模块变量,一个对象,会替换模块中,输入框内容里的`{{key}}`
{{% /alert %}}
{{< /markdownify >}}
{{< /tab >}}
{{< /tabs >}}
### 响应
@@ -747,6 +745,8 @@ curl --location --request POST 'https://api.fastgpt.in/api/v1/chat/completions'
### 请求示例
#### v1
```bash
curl --location --request POST 'http://localhost:3000/api/v1/chat/completions' \
--header 'Authorization: Bearer test-xxxxx' \
@@ -760,8 +760,25 @@ curl --location --request POST 'http://localhost:3000/api/v1/chat/completions' \
}'
```
#### v2
```bash
curl --location --request POST 'http://localhost:3000/api/v2/chat/completions' \
--header 'Authorization: Bearer test-xxxxx' \
--header 'Content-Type: application/json' \
--data-raw '{
"stream": false,
"chatId": "test",
"variables": {
"query":"你好"
}
}'
```
### 响应示例
#### v1
{{< tabs tabTotal="3" >}}
{{< tab tabName="detail=true,stream=false 响应" >}}
@@ -920,6 +937,151 @@ event取值
{{< /tab >}}
{{< /tabs >}}
#### v2
{{< tabs tabTotal="3" >}}
{{< tab tabName="detail=true,stream=false 响应" >}}
{{< markdownify >}}
* 插件的输出可以通过查找`responseData`中, `moduleType=pluginOutput`的元素,其`pluginOutput`是插件的输出。
* 流输出,仍可以通过`choices`进行获取。
```json
{
"responseData": [
{
"id": "bsH1ZdbYkz9iJwYa",
"nodeId": "pluginInput",
"moduleName": "workflow:template.plugin_start",
"moduleType": "pluginInput",
"runningTime": 0
},
{
"id": "zDgfqSPhbYZFHVIn",
"nodeId": "h4Gr4lJtFVQ6qI4c",
"moduleName": "AI 对话",
"moduleType": "chatNode",
"runningTime": 1.44,
"totalPoints": 0,
"model": "GPT-4o-mini",
"tokens": 34,
"inputTokens": 8,
"outputTokens": 26,
"query": "你好",
"reasoningText": "",
"historyPreview": [
{
"obj": "Human",
"value": "你好"
},
{
"obj": "AI",
"value": "你好!有什么我可以帮助你的吗?"
}
],
"contextTotalLen": 2
},
{
"id": "uLLwKKRZvufXzgF4",
"nodeId": "pluginOutput",
"moduleName": "common:core.module.template.self_output",
"moduleType": "pluginOutput",
"runningTime": 0,
"totalPoints": 0,
"pluginOutput": {
"result": "你好!有什么我可以帮助你的吗?"
}
}
],
"newVariables": {
},
"id": "test",
"model": "",
"usage": {
"prompt_tokens": 1,
"completion_tokens": 1,
"total_tokens": 1
},
"choices": [
{
"message": {
"role": "assistant",
"content": "你好!有什么我可以帮助你的吗?"
},
"finish_reason": "stop",
"index": 0
}
]
}
```
{{< /markdownify >}}
{{< /tab >}}
{{< tab tabName="detail=true,stream=true 响应" >}}
{{< markdownify >}}
* 插件的输出可以通过获取`event=flowResponses`中的字符串,并将其反序列化后得到一个数组。同样的,查找 `moduleType=pluginOutput`的元素,其`pluginOutput`是插件的输出。
* 流输出,仍和对话接口一样获取。
```bash
data: {"event":"flowNodeResponse","data":"{\"id\":\"q8ablUOqHGgqLIRM\",\"nodeId\":\"pluginInput\",\"moduleName\":\"workflow:template.plugin_start\",\"moduleType\":\"pluginInput\",\"runningTime\":0}"}
data: {"event":"flowNodeStatus","data":"{\"status\":\"running\",\"name\":\"AI 对话\"}"}
data: {"event":"answer","data":"{\"id\":\"\",\"object\":\"\",\"created\":0,\"model\":\"\",\"choices\":[{\"delta\":{\"role\":\"assistant\",\"content\":\"你好\"},\"index\":0,\"finish_reason\":null}]}"}
data: {"event":"answer","data":"{\"id\":\"\",\"object\":\"\",\"created\":0,\"model\":\"\",\"choices\":[{\"delta\":{\"role\":\"assistant\",\"content\":\"\"},\"index\":0,\"finish_reason\":null}]}"}
data: {"event":"answer","data":"{\"id\":\"\",\"object\":\"\",\"created\":0,\"model\":\"\",\"choices\":[{\"delta\":{\"role\":\"assistant\",\"content\":\"有什么\"},\"index\":0,\"finish_reason\":null}]}"}
data: {"event":"answer","data":"{\"id\":\"\",\"object\":\"\",\"created\":0,\"model\":\"\",\"choices\":[{\"delta\":{\"role\":\"assistant\",\"content\":\"我\"},\"index\":0,\"finish_reason\":null}]}"}
data: {"event":"answer","data":"{\"id\":\"\",\"object\":\"\",\"created\":0,\"model\":\"\",\"choices\":[{\"delta\":{\"role\":\"assistant\",\"content\":\"可以\"},\"index\":0,\"finish_reason\":null}]}"}
data: {"event":"answer","data":"{\"id\":\"\",\"object\":\"\",\"created\":0,\"model\":\"\",\"choices\":[{\"delta\":{\"role\":\"assistant\",\"content\":\"帮助\"},\"index\":0,\"finish_reason\":null}]}"}
data: {"event":"answer","data":"{\"id\":\"\",\"object\":\"\",\"created\":0,\"model\":\"\",\"choices\":[{\"delta\":{\"role\":\"assistant\",\"content\":\"你\"},\"index\":0,\"finish_reason\":null}]}"}
data: {"event":"answer","data":"{\"id\":\"\",\"object\":\"\",\"created\":0,\"model\":\"\",\"choices\":[{\"delta\":{\"role\":\"assistant\",\"content\":\"的吗\"},\"index\":0,\"finish_reason\":null}]}"}
data: {"event":"answer","data":"{\"id\":\"\",\"object\":\"\",\"created\":0,\"model\":\"\",\"choices\":[{\"delta\":{\"role\":\"assistant\",\"content\":\"\"},\"index\":0,\"finish_reason\":null}]}"}
data: {"event":"flowNodeResponse","data":"{\"id\":\"rqlXLUap8QeiN7Kf\",\"nodeId\":\"h4Gr4lJtFVQ6qI4c\",\"moduleName\":\"AI 对话\",\"moduleType\":\"chatNode\",\"runningTime\":1.79,\"totalPoints\":0,\"model\":\"GPT-4o-mini\",\"tokens\":137,\"inputTokens\":111,\"outputTokens\":26,\"query\":\"你好\",\"reasoningText\":\"\",\"historyPreview\":[{\"obj\":\"Human\",\"value\":\"[{\\\"renderTypeList\\\":[\\\"reference\\\"],\\\"selectedTypeInde\\n\\n...[hide 174 chars]...\\n\\ncanSelectImg\\\":true,\\\"required\\\":false,\\\"value\\\":\\\"你好\\\"}]\"},{\"obj\":\"AI\",\"value\":\"你好!有什么我可以帮助你的吗?\"},{\"obj\":\"Human\",\"value\":\"你好\"},{\"obj\":\"AI\",\"value\":\"你好!有什么我可以帮助你的吗?\"}],\"contextTotalLen\":4}"}
data: {"event":"flowNodeResponse","data":"{\"id\":\"lHCpHI0MrM00HQlX\",\"nodeId\":\"pluginOutput\",\"moduleName\":\"common:core.module.template.self_output\",\"moduleType\":\"pluginOutput\",\"runningTime\":0,\"totalPoints\":0,\"pluginOutput\":{\"result\":\"你好!有什么我可以帮助你的吗?\"}}"}
data: {"event":"answer","data":"{\"id\":\"\",\"object\":\"\",\"created\":0,\"model\":\"\",\"choices\":[{\"delta\":{\"role\":\"assistant\",\"content\":null},\"index\":0,\"finish_reason\":\"stop\"}]}"}
data: {"event":"answer","data":"[DONE]"}
```
{{< /markdownify >}}
{{< /tab >}}
{{< tab tabName="输出获取" >}}
{{< markdownify >}}
event取值
- answer: 返回给客户端的文本(最终会算作回答)
- fastAnswer: 指定回复返回给客户端的文本(最终会算作回答)
- toolCall: 执行工具
- toolParams: 工具参数
- toolResponse: 工具返回
- flowNodeStatus: 运行到的节点状态
- flowNodeResponse: 单个节点详细响应
- updateVariables: 更新变量
- error: 报错
{{< /markdownify >}}
{{< /tab >}}
{{< /tabs >}}
# 对话 CRUD
{{% alert icon="🤖 " context="success" %}}

View File

@@ -1,5 +1,5 @@
---
title: 'V4.9.4'
title: 'V4.9.4(进行中)'
description: 'FastGPT V4.9.4 更新说明'
icon: 'upgrade'
draft: false
@@ -11,7 +11,7 @@ weight: 796
### 1. 做好数据备份
### 2. 安装 Redis
### 1. 安装 Redis
* docker 部署的用户,参考最新的 `docker-compose.yml` 文件增加 Redis 配置。增加一个 redis 容器,并配置`fastgpt`,`fastgpt-pro`的环境变量,增加 `REDIS_URL` 环境变量。
* Sealos 部署的用户,在数据库里新建一个`redis`数据库,并复制`内网地址的 connection` 作为 `redis` 的链接串。然后配置`fastgpt`,`fastgpt-pro`的环境变量,增加 `REDIS_URL` 环境变量。
@@ -20,14 +20,10 @@ weight: 796
| --- | --- | --- |
| ![](/imgs/sealos-redis1.png) | ![](/imgs/sealos-redis2.png) | ![](/imgs/sealos-redis3.png) |
### 3. 更新镜像 tag
### 2. 更新镜像 tag
- 更新 FastGPT 镜像 tag: v4.9.4
- 更新 FastGPT 商业版镜像 tag: v4.9.4
- Sandbox 无需更新
- AIProxy 无需更新
### 4. 执行升级脚本
### 3. 执行升级脚本
该脚本仅需商业版用户执行。
@@ -49,9 +45,8 @@ curl --location --request POST 'https://{{host}}/api/admin/initv494' \
2. SMTP 发送邮件插件
3. BullMQ 消息队列。
4. 利用 redis 进行部分数据缓存。
5. 站点同步支持配置训练参数和增量同步
6. AI 对话/工具调用,增加返回模型 finish_reason 字段,便于追踪模型输出中断原因
7. 移动端语音输入交互调整
5. 站点同步支持配置训练参数。
6. AI 对话/工具调用,增加返回模型 finish_reason 字段。
## ⚙️ 优化
@@ -61,6 +56,4 @@ curl --location --request POST 'https://{{host}}/api/admin/initv494' \
## 🐛 修复
1. 搜索应用/知识库时,无法点击目录进入下一层。
2. 重新训练时,参数未成功初始化。
3. package/service 部分请求在多 app 中不一致。
1. 搜索应用/知识库时,无法点击目录进入下一层。

View File

@@ -1,29 +0,0 @@
---
title: 'V4.9.5(进行中)'
description: 'FastGPT V4.9.5 更新说明'
icon: 'upgrade'
draft: false
toc: true
weight: 795
---
## 🚀 新增内容
1. 团队成员权限细分,可分别控制是否可创建在根目录应用/知识库以及 API Key
2. 支持交互节点在嵌套工作流中使用。
3. 团队成员操作日志。
4. 用户输入节点支持多选框。
## ⚙️ 优化
1. 繁体中文翻译。
## 🐛 修复
1. password 检测规则错误。
2. 分享链接无法隐藏知识库检索结果。
3. IOS 低版本正则兼容问题。
4. 修复问答提取队列错误后,计数器未清零问题,导致问答提取队列失效。
5. Debug 模式交互节点下一步可能造成死循环。

View File

@@ -7,7 +7,7 @@ toc: true
weight: -10
---
FastGPT 是一个AI Agent 构建平台,提供开箱即用的数据处理、模型调用等能力,同时可以通过 Flow 可视化进行工作流编排,从而实现复杂的应用场景!
FastGPT 是一个AI Agent 构建平台,提供开箱即用的数据处理、模型调用等能力,同时可以通过 Flow 可视化进行工作流编排,从而实现复杂的应用场景!t
{{% alert icon="🤖 " context="success" %}}
FastGPT 在线使用:[https://tryfastgpt.ai](https://tryfastgpt.ai)

View File

@@ -12,29 +12,27 @@
"previewIcon": "node ./scripts/icon/index.js",
"api:gen": "tsc ./scripts/openapi/index.ts && node ./scripts/openapi/index.js && npx @redocly/cli build-docs ./scripts/openapi/openapi.json -o ./projects/app/public/openapi/index.html",
"create:i18n": "node ./scripts/i18n/index.js",
"test": "vitest run",
"test": "vitest run --exclude 'test/cases/spec'",
"test:all": "vitest run",
"test:workflow": "vitest run workflow"
},
"devDependencies": {
"@chakra-ui/cli": "^2.4.1",
"@vitest/coverage-v8": "^3.0.9",
"@vitest/coverage-v8": "^3.0.2",
"husky": "^8.0.3",
"i18next": "23.16.8",
"lint-staged": "^13.3.0",
"next-i18next": "15.4.2",
"prettier": "3.2.4",
"react-i18next": "14.1.2",
"vitest": "^3.0.9",
"mongodb-memory-server": "^10.1.4",
"vitest": "^3.0.2",
"vitest-mongodb": "^1.0.1",
"zhlint": "^0.7.4"
},
"lint-staged": {
"./**/**/*.{ts,tsx,scss}": "npm run format-code",
"./docSite/**/**/*.md": "npm run format-doc"
},
"resolutions": {
"mdast-util-gfm-autolink-literal": "2.0.0"
},
"engines": {
"node": ">=18.16.0",
"pnpm": ">=9.0.0"

View File

@@ -77,13 +77,6 @@ export const getHistoryPreview = (
});
};
export const filterModuleTypeList: any[] = [
FlowNodeTypeEnum.pluginModule,
FlowNodeTypeEnum.datasetSearchNode,
FlowNodeTypeEnum.tools,
FlowNodeTypeEnum.pluginOutput
];
export const filterPublicNodeResponseData = ({
flowResponses = [],
responseDetail = false
@@ -94,6 +87,12 @@ export const filterPublicNodeResponseData = ({
const filedList = responseDetail
? ['quoteList', 'moduleType', 'pluginOutput', 'runningTime']
: ['moduleType', 'pluginOutput', 'runningTime'];
const filterModuleTypeList: any[] = [
FlowNodeTypeEnum.pluginModule,
FlowNodeTypeEnum.datasetSearchNode,
FlowNodeTypeEnum.tools,
FlowNodeTypeEnum.pluginOutput
];
return flowResponses
.filter((item) => filterModuleTypeList.includes(item.moduleType))

View File

@@ -51,8 +51,7 @@ export const DatasetTypeMap = {
export enum DatasetStatusEnum {
active = 'active',
syncing = 'syncing',
waiting = 'waiting',
error = 'error'
waiting = 'waiting'
}
export const DatasetStatusMap = {
[DatasetStatusEnum.active]: {
@@ -63,9 +62,6 @@ export const DatasetStatusMap = {
},
[DatasetStatusEnum.waiting]: {
label: i18nT('common:core.dataset.status.waiting')
},
[DatasetStatusEnum.error]: {
label: i18nT('dataset:status_error')
}
};

View File

@@ -209,7 +209,6 @@ export type DatasetListItemType = {
export type DatasetItemType = Omit<DatasetSchemaType, 'vectorModel' | 'agentModel' | 'vlmModel'> & {
status: `${DatasetStatusEnum}`;
errorMsg?: string;
vectorModel: EmbeddingModelItemType;
agentModel: LLMModelItemType;
vlmModel?: LLMModelItemType;

View File

@@ -7,7 +7,6 @@ export enum FlowNodeInputTypeEnum { // render ui
numberInput = 'numberInput',
switch = 'switch', // true/false
select = 'select',
multipleSelect = 'multipleSelect',
// editor
JSONEditor = 'JSONEditor',
@@ -47,9 +46,6 @@ export const FlowNodeInputMap: Record<
[FlowNodeInputTypeEnum.select]: {
icon: 'core/workflow/inputType/option'
},
[FlowNodeInputTypeEnum.multipleSelect]: {
icon: 'core/workflow/inputType/option'
},
[FlowNodeInputTypeEnum.switch]: {
icon: 'core/workflow/inputType/switch'
},

View File

@@ -23,7 +23,7 @@ import { WorkflowResponseType } from '../../../../service/core/workflow/dispatch
import { AiChatQuoteRoleType } from '../template/system/aiChat/type';
import { LafAccountType, OpenaiAccountType } from '../../../support/user/team/type';
import { CompletionFinishReason } from '../../ai/type';
import { WorkflowInteractiveResponseType } from '../template/system/interactive/type';
export type ExternalProviderType = {
openaiAccount?: OpenaiAccountType;
externalWorkflowVariables?: Record<string, string>;
@@ -55,14 +55,12 @@ export type ChatDispatchProps = {
variables: Record<string, any>; // global variable
query: UserChatItemValueItemType[]; // trigger query
chatConfig: AppSchema['chatConfig'];
lastInteractive?: WorkflowInteractiveResponseType; // last interactive response
stream: boolean;
maxRunTimes: number;
isToolCall?: boolean;
workflowStreamResponse?: WorkflowResponseType;
workflowDispatchDeep?: number;
version?: 'v1' | 'v2';
responseDetail?: boolean;
};
export type ModuleDispatchProps<T> = ChatDispatchProps & {

View File

@@ -10,19 +10,7 @@ import { FlowNodeOutputItemType, ReferenceValueType } from '../type/io';
import { ChatItemType, NodeOutputItemType } from '../../../core/chat/type';
import { ChatItemValueTypeEnum, ChatRoleEnum } from '../../../core/chat/constants';
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 => {
let limit = 10;
nodes.forEach((node) => {
@@ -46,9 +34,7 @@ export const getMaxHistoryLimitFromNodes = (nodes: StoreNodeItemType[]): number
1. Get the interactive data
2. Check that the workflow starts at the interaction node
*/
export const getLastInteractiveValue = (
histories: ChatItemType[]
): WorkflowInteractiveResponseType | undefined => {
export const getLastInteractiveValue = (histories: ChatItemType[]) => {
const lastAIMessage = [...histories].reverse().find((item) => item.obj === ChatRoleEnum.AI);
if (lastAIMessage) {
@@ -59,11 +45,7 @@ export const getLastInteractiveValue = (
lastValue.type !== ChatItemValueTypeEnum.interactive ||
!lastValue.interactive
) {
return;
}
if (lastValue.interactive.type === 'childrenInteractive') {
return lastValue.interactive;
return null;
}
// Check is user select
@@ -80,29 +62,38 @@ export const getLastInteractiveValue = (
}
}
return;
return null;
};
export const initWorkflowEdgeStatus = (
edges: StoreEdgeItemType[],
lastInteractive?: WorkflowInteractiveResponseType
edges: StoreEdgeItemType[] | RuntimeEdgeItemType[],
histories?: ChatItemType[]
): RuntimeEdgeItemType[] => {
if (lastInteractive) {
const memoryEdges = lastInteractive.memoryEdges || [];
// If there is a history, use the last interactive value
if (histories && histories.length > 0) {
const memoryEdges = getLastInteractiveValue(histories)?.memoryEdges;
if (memoryEdges && memoryEdges.length > 0) {
return memoryEdges;
}
}
return edges?.map((edge) => ({ ...edge, status: 'waiting' })) || [];
return (
edges?.map((edge) => ({
...edge,
status: 'waiting'
})) || []
);
};
export const getWorkflowEntryNodeIds = (
nodes: (StoreNodeItemType | RuntimeNodeItemType)[],
lastInteractive?: WorkflowInteractiveResponseType
histories?: ChatItemType[]
) => {
if (lastInteractive) {
const entryNodeIds = lastInteractive.entryNodeIds || [];
// If there is a history, use the last interactive entry node
if (histories && histories.length > 0) {
const entryNodeIds = getLastInteractiveValue(histories)?.entryNodeIds;
if (Array.isArray(entryNodeIds) && entryNodeIds.length > 0) {
return entryNodeIds;
}
@@ -405,10 +396,10 @@ export const textAdaptGptResponse = ({
/* Update runtimeNode's outputs with interactive data from history */
export function rewriteNodeOutputByHistories(
runtimeNodes: RuntimeNodeItemType[],
lastInteractive?: InteractiveNodeResponseType
histories: ChatItemType[],
runtimeNodes: RuntimeNodeItemType[]
) {
const interactive = lastInteractive;
const interactive = getLastInteractiveValue(histories);
if (!interactive?.nodeOutputs) {
return runtimeNodes;
}

View File

@@ -1,5 +1,6 @@
import type { NodeOutputItemType } from '../../../../chat/type';
import type { FlowNodeOutputItemType } from '../../../type/io';
import type { RuntimeEdgeItemType } from '../../../runtime/type';
import { FlowNodeInputTypeEnum } from 'core/workflow/node/constant';
import { WorkflowIOValueTypeEnum } from 'core/workflow/constants';
import type { ChatCompletionMessageParam } from '../../../../ai/type';
@@ -8,6 +9,7 @@ type InteractiveBasicType = {
entryNodeIds: string[];
memoryEdges: RuntimeEdgeItemType[];
nodeOutputs: NodeOutputItemType[];
toolParams?: {
entryNodeIds: string[]; // 记录工具中,交互节点的 Id而不是起始工作流的入口
memoryMessages: ChatCompletionMessageParam[]; // 这轮工具中,产生的新的 messages
@@ -21,13 +23,6 @@ type InteractiveNodeType = {
nodeOutputs?: NodeOutputItemType[];
};
type ChildrenInteractive = InteractiveNodeType & {
type: 'childrenInteractive';
params: {
childrenResponse?: WorkflowInteractiveResponseType;
};
};
export type UserSelectOptionItemType = {
key: string;
value: string;
@@ -67,9 +62,5 @@ type UserInputInteractive = InteractiveNodeType & {
submitted?: boolean;
};
};
export type InteractiveNodeResponseType =
| UserSelectInteractive
| UserInputInteractive
| ChildrenInteractive;
export type InteractiveNodeResponseType = UserSelectInteractive | UserInputInteractive;
export type WorkflowInteractiveResponseType = InteractiveBasicType & InteractiveNodeResponseType;

View File

@@ -1,14 +0,0 @@
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'
}

View File

@@ -1,19 +0,0 @@
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>;
};

View File

@@ -13,15 +13,12 @@ export type CollaboratorItemType = {
orgId: string;
}>;
export type UpdateClbPermissionProps<addOnly = false> = {
export type UpdateClbPermissionProps = {
members?: string[];
groups?: string[];
orgs?: string[];
} & (addOnly extends true
? {}
: {
permission: PermissionValueType;
});
permission: PermissionValueType;
};
export type DeletePermissionQuery = RequireOnlyOne<{
tmbId?: string;

View File

@@ -5,16 +5,15 @@ export type PerConstructPros = {
per?: PermissionValueType;
isOwner?: boolean;
permissionList?: PermissionListType;
childUpdatePermissionCallback?: () => void;
};
// the Permission helper class
export class Permission {
value: PermissionValueType;
isOwner: boolean = false;
hasManagePer: boolean = false;
hasWritePer: boolean = false;
hasReadPer: boolean = false;
isOwner: boolean;
hasManagePer: boolean;
hasWritePer: boolean;
hasReadPer: boolean;
_permissionList: PermissionListType;
constructor(props?: PerConstructPros) {
@@ -25,8 +24,11 @@ export class Permission {
this.value = per;
}
this.isOwner = isOwner;
this._permissionList = permissionList;
this.updatePermissions();
this.hasManagePer = this.checkPer(this._permissionList['manage'].value);
this.hasWritePer = this.checkPer(this._permissionList['write'].value);
this.hasReadPer = this.checkPer(this._permissionList['read'].value);
}
// add permission(s)
@@ -66,21 +68,10 @@ export class Permission {
return (this.value & perm) === perm;
}
private updatePermissionCallback?: () => void;
setUpdatePermissionCallback(callback: () => void) {
callback();
this.updatePermissionCallback = callback;
}
private updatePermissions() {
this.isOwner = this.value === OwnerPermissionVal;
this.hasManagePer = this.checkPer(this._permissionList['manage'].value);
this.hasWritePer = this.checkPer(this._permissionList['write'].value);
this.hasReadPer = this.checkPer(this._permissionList['read'].value);
this.updatePermissionCallback?.();
}
toBinary() {
return this.value.toString(2);
}
}

View File

@@ -17,23 +17,23 @@ type GroupMemberSchemaType = {
role: `${GroupMemberRole}`;
};
type MemberGroupListItemType<WithMembers extends boolean | undefined> = MemberGroupSchemaType & {
members: WithMembers extends true
type MemberGroupListItemType<T extends boolean | undefined> = MemberGroupSchemaType & {
members: T extends true
? {
tmbId: string;
name: string;
avatar: string;
}[]
: undefined;
count: WithMembers extends true ? number : undefined;
owner?: WithMembers extends true
count: T extends true ? number : undefined;
owner?: T extends true
? {
tmbId: string;
name: string;
avatar: string;
}
: undefined;
permission: WithMembers extends true ? Permission : undefined;
permission: T extends true ? Permission : undefined;
};
type GroupMemberItemType = {

View File

@@ -1,50 +1,22 @@
import { PermissionKeyEnum } from '../constant';
import { PermissionListType } from '../type';
import { PermissionList } from '../constant';
import { i18nT } from '../../../../web/i18n/utils';
export enum TeamPermissionKeyEnum {
appCreate = 'appCreate',
datasetCreate = 'datasetCreate',
apikeyCreate = 'apikeyCreate'
}
export const TeamPermissionList: PermissionListType<TeamPermissionKeyEnum> = {
export const TeamPermissionList: PermissionListType = {
[PermissionKeyEnum.read]: {
...PermissionList[PermissionKeyEnum.read],
value: 0b000100
value: 0b100
},
[PermissionKeyEnum.write]: {
...PermissionList[PermissionKeyEnum.write],
value: 0b000010
value: 0b010
},
[PermissionKeyEnum.manage]: {
...PermissionList[PermissionKeyEnum.manage],
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
value: 0b001
}
};
export const TeamReadPermissionVal = TeamPermissionList['read'].value;
export const TeamWritePermissionVal = TeamPermissionList['write'].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;

View File

@@ -1,17 +1,7 @@
import { PerConstructPros, Permission } from '../controller';
import {
TeamApikeyCreatePermissionVal,
TeamAppCreatePermissionVal,
TeamDatasetCreatePermissionVal,
TeamDefaultPermissionVal,
TeamPermissionList
} from './constant';
import { TeamDefaultPermissionVal, TeamPermissionList } from './constant';
export class TeamPermission extends Permission {
hasAppCreatePer: boolean = false;
hasDatasetCreatePer: boolean = false;
hasApikeyCreatePer: boolean = false;
constructor(props?: PerConstructPros) {
if (!props) {
props = {
@@ -22,11 +12,5 @@ export class TeamPermission extends Permission {
}
props.permissionList = TeamPermissionList;
super(props);
this.setUpdatePermissionCallback(() => {
this.hasAppCreatePer = this.checkPer(TeamAppCreatePermissionVal);
this.hasDatasetCreatePer = this.checkPer(TeamDatasetCreatePermissionVal);
this.hasApikeyCreatePer = this.checkPer(TeamApikeyCreatePermissionVal);
});
}
}

View File

@@ -1,6 +1,7 @@
import { POST } from './plusRequest';
export const postTextCensor = (data: { text: string }) =>
global
.textCensorHandler(data)
POST<{ code?: number; message: string }>('/common/censor/check', data)
.then((res) => {
if (res?.code === 5000) {
return Promise.reject(res);

View File

@@ -1,29 +0,0 @@
import { FeishuServer, YuqueServer } from '@fastgpt/global/core/dataset/apiDataset';
import {
DeepRagSearchProps,
SearchDatasetDataResponse
} from '../../core/dataset/search/controller';
import { AuthOpenApiLimitProps } from '../../support/openapi/auth';
import { CreateUsageProps, ConcatUsageProps } from '@fastgpt/global/support/wallet/usage/api';
import {
GetProApiDatasetFileContentParams,
GetProApiDatasetFileListParams,
GetProApiDatasetFilePreviewUrlParams
} from '../../core/dataset/apiDataset/proApi';
declare global {
var textCensorHandler: (params: { text: string }) => Promise<{ code: number; message?: string }>;
var deepRagHandler: (data: DeepRagSearchProps) => Promise<SearchDatasetDataResponse>;
var authOpenApiHandler: (data: AuthOpenApiLimitProps) => Promise<any>;
var createUsageHandler: (data: CreateUsageProps) => Promise<void>;
var concatUsageHandler: (data: ConcatUsageProps) => Promise<void>;
// API dataset
var getProApiDatasetFileList: (data: GetProApiDatasetFileListParams) => Promise<APIFileItem[]>;
var getProApiDatasetFileContent: (
data: GetProApiDatasetFileContentParams
) => Promise<ApiFileReadContentResponse>;
var getProApiDatasetFilePreviewUrl: (
data: GetProApiDatasetFilePreviewUrlParams
) => Promise<string>;
}

View File

@@ -69,11 +69,6 @@ export function getWorker<DataType, ReturnType = void>(
newWorker.on('error', (error) => {
addLog.error(`MQ Worker [${name}]: ${error.message}`, error);
});
newWorker.on('failed', (jobId, error) => {
addLog.error(`MQ Worker [${name}]: ${error.message}`, error);
});
workers.set(name, newWorker);
return newWorker;
}
export * from 'bullmq';

View File

@@ -69,7 +69,7 @@ const addCommonMiddleware = (schema: mongoose.Schema) => {
export const getMongoModel = <T>(name: string, schema: mongoose.Schema) => {
if (connectionMongo.models[name]) return connectionMongo.models[name] as Model<T>;
if (process.env.NODE_ENV !== 'test') console.log('Load model======', name);
console.log('Load model======', name);
addCommonMiddleware(schema);
const model = connectionMongo.model<T>(name, schema);

View File

@@ -1,3 +1,4 @@
export const FastGPTProUrl = process.env.PRO_URL ? `${process.env.PRO_URL}/api` : '';
export const isFastGPTMainService = !!process.env.PRO_URL;
// @ts-ignore
export const isFastGPTProService = () => !!global.systemConfig;

View File

@@ -7,8 +7,6 @@ import { EmbeddingModelItemType } from '@fastgpt/global/core/ai/model.d';
import { MILVUS_ADDRESS, PG_ADDRESS, OCEANBASE_ADDRESS } from './constants';
import { MilvusCtrl } from './milvus/class';
import { setRedisCache, getRedisCache, delRedisCache, CacheKeyEnum } from '../redis/cache';
import { throttle } from 'lodash';
import { retryFn } from '@fastgpt/global/common/system/utils';
const getVectorObj = () => {
if (PG_ADDRESS) return new PgVectorCtrl();
@@ -17,12 +15,7 @@ const getVectorObj = () => {
return new PgVectorCtrl();
};
const getChcheKey = (teamId: string) => `${CacheKeyEnum.team_vector_count}:${teamId}`;
const onDelCache = throttle((teamId: string) => delRedisCache(getChcheKey(teamId)), 30000, {
leading: true,
trailing: true
});
const Vector = getVectorObj();
@@ -56,28 +49,26 @@ export const insertDatasetDataVector = async ({
query: string;
model: EmbeddingModelItemType;
}) => {
return retryFn(async () => {
const { vectors, tokens } = await getVectorsByText({
model,
input: query,
type: 'db'
});
const { insertId } = await Vector.insert({
...props,
vector: vectors[0]
});
onDelCache(props.teamId);
return {
tokens,
insertId
};
const { vectors, tokens } = await getVectorsByText({
model,
input: query,
type: 'db'
});
const { insertId } = await Vector.insert({
...props,
vector: vectors[0]
});
delRedisCache(getChcheKey(props.teamId));
return {
tokens,
insertId
};
};
export const deleteDatasetDataVector = async (props: DelDatasetVectorCtrlProps) => {
const result = await Vector.delete(props);
onDelCache(props.teamId);
delRedisCache(getChcheKey(props.teamId));
return result;
};

View File

@@ -16,7 +16,6 @@ import { mergeChatResponseData } from '@fastgpt/global/core/chat/utils';
import { pushChatLog } from './pushChatLog';
import { FlowNodeTypeEnum } from '@fastgpt/global/core/workflow/node/constant';
import { DispatchNodeResponseKeyEnum } from '@fastgpt/global/core/workflow/runtime/constants';
import { extractDeepestInteractive } from '@fastgpt/global/core/workflow/runtime/utils';
type Props = {
chatId: string;
@@ -210,24 +209,34 @@ export const updateInteractiveChat = async ({
}
})();
let finalInteractive = extractDeepestInteractive(interactiveValue.interactive);
if (finalInteractive.type === 'userSelect') {
finalInteractive.params.userSelectedVal = userInteractiveVal;
if (interactiveValue.interactive.type === 'userSelect') {
interactiveValue.interactive = {
...interactiveValue.interactive,
params: {
...interactiveValue.interactive.params,
userSelectedVal: userInteractiveVal
}
};
} else if (
finalInteractive.type === 'userInput' &&
interactiveValue.interactive.type === 'userInput' &&
typeof parsedUserInteractiveVal === 'object'
) {
finalInteractive.params.inputForm = finalInteractive.params.inputForm.map((item) => {
const itemValue = parsedUserInteractiveVal[item.label];
return itemValue !== undefined
? {
...item,
value: itemValue
}
: item;
});
finalInteractive.params.submitted = true;
interactiveValue.interactive = {
...interactiveValue.interactive,
params: {
...interactiveValue.interactive.params,
inputForm: interactiveValue.interactive.params.inputForm.map((item) => {
const itemValue = parsedUserInteractiveVal[item.label];
return itemValue !== undefined
? {
...item,
value: itemValue
}
: item;
}),
submitted: true
}
};
}
if (aiResponse.customFeedbacks) {

View File

@@ -1,25 +0,0 @@
import { ParentIdType } from '@fastgpt/global/common/parentFolder/type';
import { FeishuServer, YuqueServer } from '@fastgpt/global/core/dataset/apiDataset';
export enum ProApiDatasetOperationTypeEnum {
LIST = 'list',
READ = 'read',
CONTENT = 'content'
}
export type ProApiDatasetCommonParams = {
feishuServer?: FeishuServer;
yuqueServer?: YuqueServer;
};
export type GetProApiDatasetFileListParams = ProApiDatasetCommonParams & {
parentId?: ParentIdType;
};
export type GetProApiDatasetFileContentParams = ProApiDatasetCommonParams & {
apiFileId: string;
};
export type GetProApiDatasetFilePreviewUrlParams = ProApiDatasetCommonParams & {
apiFileId: string;
};

View File

@@ -9,6 +9,7 @@ import { readRawContentByFileBuffer } from '../../common/file/read/utils';
import { parseFileExtensionFromUrl } from '@fastgpt/global/common/string/tools';
import { APIFileServer, FeishuServer, YuqueServer } from '@fastgpt/global/core/dataset/apiDataset';
import { useApiDatasetRequest } from './apiDataset/api';
import { POST } from '../../common/api/plusRequest';
export const readFileRawTextByUrl = async ({
teamId,
@@ -167,7 +168,11 @@ export const readApiServerFileContent = async ({
}
if (feishuServer || yuqueServer) {
return global.getProApiDatasetFileContent({
return POST<{
title?: string;
rawText: string;
}>(`/core/dataset/systemApiDataset`, {
type: 'content',
feishuServer,
yuqueServer,
apiFileId

View File

@@ -24,6 +24,7 @@ import { MongoDatasetCollectionTags } from '../tag/schema';
import { readFromSecondary } from '../../../common/mongo/utils';
import { MongoDatasetDataText } from '../data/dataTextSchema';
import { ChatItemType } from '@fastgpt/global/core/chat/type';
import { POST } from '../../../common/api/plusRequest';
import { NodeInputKeyEnum } from '@fastgpt/global/core/workflow/constants';
import { datasetSearchQueryExtension } from './utils';
import type { RerankModelItemType } from '@fastgpt/global/core/ai/model.d';
@@ -849,4 +850,5 @@ export type DeepRagSearchProps = SearchDatasetDataProps & {
[NodeInputKeyEnum.datasetDeepSearchMaxTimes]?: number;
[NodeInputKeyEnum.datasetDeepSearchBg]?: string;
};
export const deepRagSearch = (data: DeepRagSearchProps) => global.deepRagHandler(data);
export const deepRagSearch = (data: DeepRagSearchProps) =>
POST<SearchDatasetDataResponse>('/core/dataset/deepRag', data);

View File

@@ -34,44 +34,23 @@ export const addWebsiteSyncJob = (data: WebsiteSyncJobData) => {
export const getWebsiteSyncDatasetStatus = async (datasetId: string) => {
const jobId = await websiteSyncQueue.getDeduplicationJobId(datasetId);
if (!jobId) {
return {
status: DatasetStatusEnum.active,
errorMsg: undefined
};
return DatasetStatusEnum.active;
}
const job = await websiteSyncQueue.getJob(jobId);
if (!job) {
return {
status: DatasetStatusEnum.active,
errorMsg: undefined
};
return DatasetStatusEnum.active;
}
const jobState = await job.getState();
if (jobState === 'failed' || jobState === 'unknown') {
return {
status: DatasetStatusEnum.error,
errorMsg: job.failedReason
};
}
if (['waiting-children', 'waiting'].includes(jobState)) {
return {
status: DatasetStatusEnum.waiting,
errorMsg: undefined
};
return DatasetStatusEnum.waiting;
}
if (jobState === 'active') {
return {
status: DatasetStatusEnum.syncing,
errorMsg: undefined
};
return DatasetStatusEnum.syncing;
}
return {
status: DatasetStatusEnum.active,
errorMsg: undefined
};
return DatasetStatusEnum.active;
};
// Scheduler setting

View File

@@ -29,9 +29,9 @@ import { InteractiveNodeResponseType } from '@fastgpt/global/core/workflow/templ
import { getFileContentFromLinks, getHistoryFileLinks } from '../../tools/readFiles';
import { parseUrlToFileType } from '@fastgpt/global/common/file/tools';
import { FlowNodeTypeEnum } from '@fastgpt/global/core/workflow/node/constant';
import { postTextCensor } from '../../../../../common/api/requestPlusApi';
import { ModelTypeEnum } from '@fastgpt/global/core/ai/model';
import { getDocumentQuotePrompt } from '@fastgpt/global/core/ai/prompt/AIChat';
import { postTextCensor } from '../../../../chat/postTextCensor';
type Response = DispatchNodeResultType<{
[NodeOutputKeyEnum.answerText]: string;

View File

@@ -13,6 +13,7 @@ import type {
} from '@fastgpt/global/core/ai/type.d';
import { formatModelChars2Points } from '../../../../support/wallet/usage/utils';
import type { LLMModelItemType } from '@fastgpt/global/core/ai/model.d';
import { postTextCensor } from '../../../../common/api/requestPlusApi';
import { ChatCompletionRequestMessageRoleEnum } from '@fastgpt/global/core/ai/constants';
import type {
ChatDispatchProps,
@@ -50,7 +51,6 @@ import { getFileContentFromLinks, getHistoryFileLinks } from '../tools/readFiles
import { parseUrlToFileType } from '@fastgpt/global/common/file/tools';
import { i18nT } from '../../../../../web/i18n/utils';
import { ModelTypeEnum } from '@fastgpt/global/core/ai/model';
import { postTextCensor } from '../../../chat/postTextCensor';
export type ChatProps = ModuleDispatchProps<
AIChatNodeProps & {

View File

@@ -73,7 +73,6 @@ import { dispatchLoopStart } from './loop/runLoopStart';
import { dispatchFormInput } from './interactive/formInput';
import { dispatchToolParams } from './agent/runTool/toolParams';
import { getErrText } from '@fastgpt/global/common/error/utils';
import { filterModuleTypeList } from '@fastgpt/global/core/chat/utils';
const callbackMap: Record<FlowNodeTypeEnum, Function> = {
[FlowNodeTypeEnum.workflowStart]: dispatchWorkflowStart,
@@ -132,7 +131,6 @@ export async function dispatchWorkFlow(data: Props): Promise<DispatchFlowRespons
externalProvider,
stream = false,
version = 'v1',
responseDetail = true,
...props
} = data;
@@ -142,7 +140,6 @@ export async function dispatchWorkFlow(data: Props): Promise<DispatchFlowRespons
} else {
props.workflowDispatchDeep += 1;
}
const isRootRuntime = props.workflowDispatchDeep === 1;
if (props.workflowDispatchDeep > 20) {
return {
@@ -163,28 +160,25 @@ export async function dispatchWorkFlow(data: Props): Promise<DispatchFlowRespons
let workflowRunTimes = 0;
// set sse response headers
if (isRootRuntime) {
res?.setHeader('Connection', 'keep-alive'); // Set keepalive for long connection
if (stream && res) {
res.setHeader('Content-Type', 'text/event-stream;charset=utf-8');
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('X-Accel-Buffering', 'no');
res.setHeader('Cache-Control', 'no-cache, no-transform');
if (stream && res) {
res.setHeader('Content-Type', 'text/event-stream;charset=utf-8');
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
const sendStreamTimerSign = () => {
setTimeout(() => {
props?.workflowStreamResponse?.({
event: SseResponseEventEnum.answer,
data: textAdaptGptResponse({
text: ''
})
});
sendStreamTimerSign();
}, 10000);
};
sendStreamTimerSign();
}
// 10s sends a message to prevent the browser from thinking that the connection is disconnected
const sendStreamTimerSign = () => {
setTimeout(() => {
props?.workflowStreamResponse?.({
event: SseResponseEventEnum.answer,
data: textAdaptGptResponse({
text: ''
})
});
sendStreamTimerSign();
}, 10000);
};
sendStreamTimerSign();
}
variables = {
@@ -330,9 +324,10 @@ export async function dispatchWorkFlow(data: Props): Promise<DispatchFlowRespons
});
if (props.mode === 'debug') {
debugNextStepRunNodes = debugNextStepRunNodes.concat(
props.lastInteractive ? nextStepActiveNodes : [...nextStepActiveNodes, ...nextStepSkipNodes]
);
debugNextStepRunNodes = debugNextStepRunNodes.concat([
...nextStepActiveNodes,
...nextStepSkipNodes
]);
return {
nextStepActiveNodes: [],
nextStepSkipNodes: []
@@ -378,7 +373,7 @@ export async function dispatchWorkFlow(data: Props): Promise<DispatchFlowRespons
};
// Tool call, not need interactive response
if (!props.isToolCall && isRootRuntime) {
if (!props.isToolCall) {
props.workflowStreamResponse?.({
event: SseResponseEventEnum.interactive,
data: { interactive: interactiveResult }
@@ -432,6 +427,14 @@ export async function dispatchWorkFlow(data: Props): Promise<DispatchFlowRespons
})();
if (!nodeRunResult) return [];
if (res?.closed) {
addLog.warn('Request is closed', {
appId: props.runningAppInfo.id,
nodeId: node.nodeId,
nodeName: node.name
});
return [];
}
/*
特殊情况:
@@ -488,15 +491,6 @@ export async function dispatchWorkFlow(data: Props): Promise<DispatchFlowRespons
await Promise.all(nextStepSkipNodes.map((node) => checkNodeCanRun(node, skippedNodeIdList)))
).flat();
if (res?.closed) {
addLog.warn('Request is closed', {
appId: props.runningAppInfo.id,
nodeId: node.nodeId,
nodeName: node.name
});
return [];
}
return [
...nextStepActiveNodes,
...nextStepSkipNodes,
@@ -637,9 +631,8 @@ export async function dispatchWorkFlow(data: Props): Promise<DispatchFlowRespons
if (
version === 'v2' &&
!props.isToolCall &&
isRootRuntime &&
formatResponseData &&
!(responseDetail === false && filterModuleTypeList.includes(formatResponseData.moduleType))
!props.runningAppInfo.isChildApp &&
formatResponseData
) {
props.workflowStreamResponse?.({
event: SseResponseEventEnum.flowNodeResponse,
@@ -726,9 +719,7 @@ export async function dispatchWorkFlow(data: Props): Promise<DispatchFlowRespons
entryNodeIds: nodeInteractiveResponse.entryNodeIds,
interactiveResponse: nodeInteractiveResponse.interactiveResponse
});
if (isRootRuntime) {
chatAssistantResponse.push(interactiveAssistant);
}
chatAssistantResponse.push(interactiveAssistant);
return interactiveAssistant.interactive;
}
})();

View File

@@ -10,6 +10,7 @@ import type {
UserInputInteractive
} from '@fastgpt/global/core/workflow/template/system/interactive/type';
import { addLog } from '../../../../common/system/log';
import { getLastInteractiveValue } from '@fastgpt/global/core/workflow/runtime/utils';
type Props = ModuleDispatchProps<{
[NodeInputKeyEnum.description]: string;
@@ -28,13 +29,13 @@ export const dispatchFormInput = async (props: Props): Promise<FormInputResponse
histories,
node,
params: { description, userInputForms },
query,
lastInteractive
query
} = props;
const { isEntry } = node;
const interactive = getLastInteractiveValue(histories);
// Interactive node is not the entry node, return interactive result
if (!isEntry || lastInteractive?.type !== 'userInput') {
if (!isEntry || interactive?.type !== 'userInput') {
return {
[DispatchNodeResponseKeyEnum.interactive]: {
type: 'userInput',

View File

@@ -10,6 +10,7 @@ import type {
UserSelectOptionItemType
} from '@fastgpt/global/core/workflow/template/system/interactive/type';
import { chatValue2RuntimePrompt } from '@fastgpt/global/core/chat/adapt';
import { getLastInteractiveValue } from '@fastgpt/global/core/workflow/runtime/utils';
type Props = ModuleDispatchProps<{
[NodeInputKeyEnum.description]: string;
@@ -26,13 +27,13 @@ export const dispatchUserSelect = async (props: Props): Promise<UserSelectRespon
histories,
node,
params: { description, userSelectOptions },
query,
lastInteractive
query
} = props;
const { nodeId, isEntry } = node;
const interactive = getLastInteractiveValue(histories);
// Interactive node is not the entry node, return interactive result
if (!isEntry || lastInteractive?.type !== 'userSelect') {
if (!isEntry || interactive?.type !== 'userSelect') {
return {
[DispatchNodeResponseKeyEnum.interactive]: {
type: 'userSelect',

View File

@@ -33,7 +33,7 @@ export const dispatchLoop = async (props: Props): Promise<Response> => {
? Number(process.env.WORKFLOW_MAX_LOOP_TIMES)
: 50;
if (loopInputArray.length > maxLength) {
return Promise.reject(`Input array length cannot be greater than ${maxLength}`);
return Promise.reject('Input array length cannot be greater than 50');
}
const outputValueArr = [];

View File

@@ -18,7 +18,6 @@ import { authAppByTmbId } from '../../../../support/permission/app/auth';
import { ReadPermissionVal } from '@fastgpt/global/support/permission/constant';
import { getAppVersionById } from '../../../app/version/controller';
import { parseUrlToFileType } from '@fastgpt/global/common/file/tools';
import { ChildrenInteractive } from '@fastgpt/global/core/workflow/template/system/interactive/type';
type Props = ModuleDispatchProps<{
[NodeInputKeyEnum.userChatInput]: string;
@@ -28,7 +27,6 @@ type Props = ModuleDispatchProps<{
[NodeInputKeyEnum.fileUrlList]?: string[];
}>;
type Response = DispatchNodeResultType<{
[DispatchNodeResponseKeyEnum.interactive]?: ChildrenInteractive;
[NodeOutputKeyEnum.answerText]: string;
[NodeOutputKeyEnum.history]: ChatItemType[];
}>;
@@ -38,7 +36,6 @@ export const dispatchRunAppNode = async (props: Props): Promise<Response> => {
runningAppInfo,
histories,
query,
lastInteractive,
node: { pluginId: appId, version },
workflowStreamResponse,
params,
@@ -103,41 +100,31 @@ export const dispatchRunAppNode = async (props: Props): Promise<Response> => {
appId: String(appData._id)
};
const childrenInteractive =
lastInteractive?.type === 'childrenInteractive'
? lastInteractive.params.childrenResponse
: undefined;
const entryNodeIds = getWorkflowEntryNodeIds(nodes, childrenInteractive || undefined);
const runtimeNodes = storeNodes2RuntimeNodes(nodes, entryNodeIds);
const runtimeEdges = initWorkflowEdgeStatus(edges, childrenInteractive);
const theQuery = childrenInteractive
? query
: runtimePrompt2ChatsValue({ files: userInputFiles, text: userChatInput });
const { flowResponses, flowUsages, assistantResponses, runTimes, workflowInteractiveResponse } =
await dispatchWorkFlow({
...props,
lastInteractive: childrenInteractive,
// Rewrite stream mode
...(system_forbid_stream
? {
stream: false,
workflowStreamResponse: undefined
}
: {}),
runningAppInfo: {
id: String(appData._id),
teamId: String(appData.teamId),
tmbId: String(appData.tmbId),
isChildApp: true
},
runtimeNodes,
runtimeEdges,
histories: chatHistories,
variables: childrenRunVariables,
query: theQuery,
chatConfig
});
const { flowResponses, flowUsages, assistantResponses, runTimes } = await dispatchWorkFlow({
...props,
// Rewrite stream mode
...(system_forbid_stream
? {
stream: false,
workflowStreamResponse: undefined
}
: {}),
runningAppInfo: {
id: String(appData._id),
teamId: String(appData.teamId),
tmbId: String(appData.tmbId),
isChildApp: true
},
runtimeNodes: storeNodes2RuntimeNodes(nodes, getWorkflowEntryNodeIds(nodes)),
runtimeEdges: initWorkflowEdgeStatus(edges),
histories: chatHistories,
variables: childrenRunVariables,
query: runtimePrompt2ChatsValue({
files: userInputFiles,
text: userChatInput
}),
chatConfig
});
const completeMessages = chatHistories.concat([
{
@@ -155,14 +142,6 @@ export const dispatchRunAppNode = async (props: Props): Promise<Response> => {
const usagePoints = flowUsages.reduce((sum, item) => sum + (item.totalPoints || 0), 0);
return {
[DispatchNodeResponseKeyEnum.interactive]: workflowInteractiveResponse
? {
type: 'childrenInteractive',
params: {
childrenResponse: workflowInteractiveResponse
}
}
: undefined,
assistantResponses: system_forbid_stream ? [] : assistantResponses,
[DispatchNodeResponseKeyEnum.runTimes]: runTimes,
[DispatchNodeResponseKeyEnum.nodeResponse]: {

View File

@@ -34,7 +34,7 @@
"node-cron": "^3.0.3",
"node-xlsx": "^0.24.0",
"papaparse": "5.4.1",
"pdfjs-dist": "4.10.38",
"pdfjs-dist": "4.4.168",
"pg": "^8.10.0",
"request-ip": "^3.3.0",
"tiktoken": "1.0.17",

View File

@@ -1,6 +1,7 @@
import { ERROR_ENUM } from '@fastgpt/global/common/error/errorCode';
import { updateApiKeyUsedTime } from './tools';
import { MongoOpenApi } from './schema';
import { POST } from '../../common/api/plusRequest';
import type { OpenApiSchema } from '@fastgpt/global/support/openapi/type';
export type AuthOpenApiLimitProps = { openApi: OpenApiSchema };
@@ -16,10 +17,11 @@ export async function authOpenApiKey({ apikey }: { apikey: string }) {
}
// auth limit
// @ts-ignore
if (global.feConfigs?.isPlus) {
await global.authOpenApiHandler({
await POST('/support/openapi/authLimit', {
openApi
});
} as AuthOpenApiLimitProps);
}
updateApiKeyUsedTime(openApi._id);

View File

@@ -1,26 +0,0 @@
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
})
);
}

View File

@@ -1,85 +0,0 @@
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;
};
};

View File

@@ -1,40 +0,0 @@
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
);

View File

@@ -2,7 +2,7 @@ import { TeamPermission } from '@fastgpt/global/support/permission/user/controll
import { AuthModeType, AuthResponseType } from '../type';
import { TeamErrEnum } from '@fastgpt/global/common/error/code/team';
import { authUserPer } from '../user/auth';
import { TeamManagePermissionVal } from '@fastgpt/global/support/permission/user/constant';
import { ManagePermissionVal } from '@fastgpt/global/support/permission/constant';
/*
Team manager can control org
@@ -15,7 +15,7 @@ export const authOrgMember = async ({
} & AuthModeType): Promise<AuthResponseType> => {
const result = await authUserPer({
...props,
per: TeamManagePermissionVal
per: ManagePermissionVal
});
const { teamId, tmbId, isRoot, tmb } = result;

View File

@@ -104,11 +104,8 @@ export async function addSourceMember<T extends { tmbId: string }>({
const tmb = tmbList.find((tmb) => String(tmb._id) === String(item.tmbId));
if (!tmb) return;
// @ts-ignore
const formatItem = typeof item.toObject === 'function' ? item.toObject() : item;
return {
...formatItem,
...item,
sourceMember: { name: tmb.name, avatar: tmb.avatar, status: tmb.status }
};
})

View File

@@ -1,21 +1,67 @@
import { UsageSourceEnum } from '@fastgpt/global/support/wallet/usage/constants';
import { MongoUsage } from './schema';
import { ClientSession } from '../../../common/mongo';
import { ClientSession, Types } from '../../../common/mongo';
import { addLog } from '../../../common/system/log';
import { ChatNodeUsageType } from '@fastgpt/global/support/wallet/bill/type';
import { ConcatUsageProps, CreateUsageProps } from '@fastgpt/global/support/wallet/usage/api';
import { i18nT } from '../../../../web/i18n/utils';
import { pushConcatBillTask, pushReduceTeamAiPointsTask } from './utils';
import { POST } from '../../../common/api/plusRequest';
import { isFastGPTMainService } from '../../../common/system/constants';
export async function createUsage(data: CreateUsageProps) {
try {
await global.createUsageHandler(data);
// In FastGPT server
if (isFastGPTMainService) {
await POST('/support/wallet/usage/createUsage', data);
} else if (global.reduceAiPointsQueue) {
// In FastGPT pro server
await MongoUsage.create(data);
pushReduceTeamAiPointsTask({ teamId: data.teamId, totalPoints: data.totalPoints });
if (data.totalPoints === 0) {
addLog.info('0 totalPoints', data);
}
}
} catch (error) {
addLog.error('createUsage error', error);
}
}
export async function concatUsage(data: ConcatUsageProps) {
try {
await global.concatUsageHandler(data);
// In FastGPT server
if (isFastGPTMainService) {
await POST('/support/wallet/usage/concatUsage', data);
} else if (global.reduceAiPointsQueue) {
const {
teamId,
billId,
totalPoints = 0,
listIndex,
inputTokens = 0,
outputTokens = 0
} = data;
// billId is required and valid
if (!billId || !Types.ObjectId.isValid(billId)) return;
// In FastGPT pro server
pushConcatBillTask([
{
billId,
listIndex,
inputTokens,
outputTokens,
totalPoints
}
]);
pushReduceTeamAiPointsTask({ teamId, totalPoints });
if (data.totalPoints === 0) {
addLog.info('0 totalPoints', data);
}
}
} catch (error) {
addLog.error('concatUsage error', error);
}

View File

@@ -1,5 +1,6 @@
import { findAIModel } from '../../../core/ai/model';
import { ModelTypeEnum } from '@fastgpt/global/core/ai/model';
import { ConcatBillQueueItemType } from './type';
export const formatModelChars2Points = ({
model,
@@ -34,3 +35,20 @@ export const formatModelChars2Points = ({
totalPoints
};
};
export const pushReduceTeamAiPointsTask = ({
teamId,
totalPoints
}: {
teamId: string;
totalPoints: number;
}) => {
global.reduceAiPointsQueue.push({
teamId: String(teamId),
totalPoints
});
};
export const pushConcatBillTask = (data: ConcatBillQueueItemType[]) => {
global.concatBillQueue.push(...data);
};

View File

@@ -1,6 +1,5 @@
import {
Box,
Button,
ButtonProps,
Checkbox,
Flex,
@@ -27,14 +26,13 @@ export type SelectProps<T = any> = {
}[];
value: T[];
isSelectAll: boolean;
setIsSelectAll?: React.Dispatch<React.SetStateAction<boolean>>;
setIsSelectAll: React.Dispatch<React.SetStateAction<boolean>>;
placeholder?: string;
maxH?: number;
itemWrap?: boolean;
onSelect: (val: T[]) => void;
closeable?: boolean;
isDisabled?: boolean;
ScrollData?: ReturnType<typeof useScrollPagination>['ScrollData'];
} & Omit<ButtonProps, 'onSelect'>;
@@ -49,7 +47,6 @@ const MultipleSelect = <T = any,>({
ScrollData,
isSelectAll,
setIsSelectAll,
isDisabled = false,
...props
}: SelectProps<T>) => {
const ref = useRef<HTMLButtonElement>(null);
@@ -73,7 +70,7 @@ const MultipleSelect = <T = any,>({
// 全选状态下value 实际上上空。
if (isSelectAll) {
onSelect(list.map((item) => item.value).filter((i) => i !== val));
setIsSelectAll?.(false);
setIsSelectAll(false);
return;
}
@@ -90,7 +87,7 @@ const MultipleSelect = <T = any,>({
const hasSelected = isSelectAll || value.length > 0;
onSelect(hasSelected ? [] : list.map((item) => item.value));
setIsSelectAll?.((state) => !state);
setIsSelectAll((state) => !state);
}, [value, list, setIsSelectAll, onSelect]);
const ListRender = useMemo(() => {
@@ -129,11 +126,11 @@ const MultipleSelect = <T = any,>({
}, [value, list, isSelectAll]);
return (
<Box h={'100%'} w={'100%'}>
<Box>
<Menu
autoSelect={false}
isOpen={isOpen && !isDisabled}
onOpen={isDisabled ? undefined : onOpen}
isOpen={isOpen}
onOpen={onOpen}
onClose={onClose}
strategy={'fixed'}
matchWidth
@@ -141,23 +138,21 @@ const MultipleSelect = <T = any,>({
>
<MenuButton
as={Flex}
h={'100%'}
alignItems={'center'}
ref={ref}
px={3}
borderRadius={'md'}
border={'base'}
userSelect={'none'}
cursor={isDisabled ? 'not-allowed' : 'pointer'}
cursor={'pointer'}
_active={{
transform: 'none'
}}
_hover={{
borderColor: isDisabled ? 'myGray.200' : 'primary.300'
borderColor: 'primary.300'
}}
opacity={isDisabled ? 0.6 : 1}
{...props}
{...(isOpen && !isDisabled
{...(isOpen
? {
boxShadow: '0px 0px 4px #A8DBFF',
borderColor: 'primary.500',

View File

@@ -5,23 +5,17 @@
"7days": "7 Days",
"accept": "accept",
"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_member": "Confirm to delete member?",
"confirm_delete_org": "Confirm to delete organization?",
"confirm_forbidden": "Confirm forbidden",
"confirm_leave_team": "Confirmed to leave the team? \nAfter exiting, all your resources in the team are transferred to the team owner.",
"copy_link": "Copy link",
"create_department": "Create a sub-department",
"create_group": "Create group",
"create_invitation_link": "Create Invitation Link",
"create_org": "Create organization",
"create_sub_org": "Create sub-organization",
"delete": "delete",
"delete_department": "Delete sub-department",
"delete_group": "Delete a group",
"delete_org": "Delete organization",
"edit_info": "Edit information",
"edit_member": "Edit user",
@@ -43,51 +37,21 @@
"invitation_link_list": "Invitation link list",
"invite_member": "Invite members",
"invited": "Invited",
"join_team": "Join the team",
"kick_out_team": "Remove members",
"label_sync": "Tag sync",
"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",
"member": "member",
"member_group": "Belonging to member group",
"move_member": "Move member",
"move_org": "Move organization",
"operation_log": "log",
"org": "organization",
"org_description": "Organization description",
"org_name": "Organization name",
"owner": "owner",
"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",
"remove_tip": "Confirm to remove {{username}} from the team?",
"retain_admin_permissions": "Keep administrator rights",
"search_log": "Search log",
"search_member_group_name": "Search member/group name",
"total_team_members": "{{amount}} members in total",
"transfer_ownership": "transfer owner",

View File

@@ -97,7 +97,7 @@
"permission.des.read": "View knowledge base content",
"permission.des.write": "Ability to add and change knowledge base content",
"preview_chunk": "Preview chunks",
"preview_chunk_empty": "File content is empty",
"preview_chunk_empty": "Unable to read the contents of the file",
"preview_chunk_intro": "A total of {{total}} blocks, up to 10",
"preview_chunk_not_selected": "Click on the file on the left to preview",
"process.Auto_Index": "Automatic index generation",
@@ -124,7 +124,6 @@
"split_sign_question": "question mark",
"split_sign_semicolon": "semicolon",
"start_sync_website_tip": "Confirm to start synchronizing data? \nThe old data will be deleted and retrieved again, please confirm!",
"status_error": "Running exception",
"sync_collection_failed": "Synchronization collection error, please check whether the source file can be accessed normally",
"sync_schedule": "Timing synchronization",
"sync_schedule_tip": "Only existing collections will be synchronized. \nIncludes linked collections and all collections in the API knowledge base. \nThe system will poll for updates every day, and the specific update time cannot be determined.",

View File

@@ -100,6 +100,7 @@
"team.group.manage_tip": "Can manage members, create groups, manage all groups, assign permissions to groups and members",
"team.group.members": "member",
"team.group.name": "Group name",
"team.group.permission.manage": "administrator",
"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.role.admin": "administrator",
@@ -111,6 +112,5 @@
"team.manage_collaborators": "Manage Collaborators",
"team.no_collaborators": "No Collaborators",
"team.org.org": "Organization",
"team.write_role_member": "Write Permission",
"team.collaborator.added": "Added"
"team.write_role_member": ""
}

View File

@@ -77,7 +77,6 @@
"ifelse.Input value": "Input Value",
"ifelse.Select value": "Select Value",
"input_description": "Field Description",
"input_type_multiple_select": "Multiple selection boxes",
"input_variable_list": "Type / to invoke variable list",
"intro_assigned_reply": "This module can directly reply with a specified content. Commonly used for guidance or prompts. Non-string content will be converted to string for output.",
"intro_custom_feedback": "When this module is triggered, a feedback will be added to the current conversation record. It can be used to automatically record conversation effects, etc.",
@@ -153,7 +152,6 @@
"response.read files": "Read Files",
"select_an_application": "Select an Application",
"select_another_application_to_call": "You can choose another application to call",
"select_default_option": "Select the default value",
"special_array_format": "Special array format, returns an empty array when the search result is empty.",
"start_with": "Starts With",
"support_code_language": "Support import list: pandasnumpy",

View File

@@ -5,9 +5,6 @@
"7days": "7天",
"accept": "接受",
"action": "操作",
"assign_permission": "权限变更",
"change_department_name": "部门编辑",
"change_member_name": "成员改名",
"confirm_delete_from_org": "确认将 {{username}} 移出部门?",
"confirm_delete_from_team": "确认将 {{username}} 移出团队?",
"confirm_delete_group": "确认删除群组?",
@@ -15,16 +12,13 @@
"confirm_forbidden": "确认停用",
"confirm_leave_team": "确认离开该团队? \n退出后您在该团队所有的资源均转让给团队所有者。",
"copy_link": "复制链接",
"create_department": "创建子部门",
"create_group": "创建群组",
"create_invitation_link": "创建邀请链接",
"create_org": "创建部门",
"create_sub_org": "创建子部门",
"delete": "删除",
"delete_department": "删除子部门",
"delete_from_org": "移出部门",
"delete_from_team": "移出团队",
"delete_group": "删除群组",
"delete_org": "删除部门",
"edit_info": "编辑信息",
"edit_member": "编辑用户",
@@ -47,37 +41,27 @@
"invitation_link_list": "链接列表",
"invite_member": "邀请成员",
"invited": "已邀请",
"join_team": "加入团队",
"join_update_time": "加入/更新时间",
"kick_out_team": "移除成员",
"label_sync": "标签同步",
"leave": "已离职",
"leave_team_failed": "离开团队异常",
"log_details": "详情",
"log_time": "操作时间",
"log_type": "操作类型",
"log_user": "操作人员",
"login": "登录",
"manage_member": "管理成员",
"member": "成员",
"member_group": "所属群组",
"move_member": "移动成员",
"move_org": "移动部门",
"notification_recieve": "团队通知接收",
"operation_log": "日志",
"org": "部门",
"org_description": "介绍",
"org_name": "部门名称",
"owner": "所有者",
"permission": "权限",
"please_bind_contact": "请绑定联系方式",
"relocate_department": "部门移动",
"remark": "备注",
"remove_tip": "确认将 {{username}} 移出团队?成员将被标记为“已离职”,不删除操作数据,账号下资源自动转让给团队所有者。",
"restore_tip": "确认将 {{username}} 加入团队吗?仅恢复该成员账号可用性及相关权限,无法恢复账号下资源。",
"restore_tip_title": "恢复确认",
"retain_admin_permissions": "保留管理员权限",
"search_log": "搜索日志",
"search_member": "搜索成员",
"search_member_group_name": "搜索成员/群组名称",
"search_org": "搜索部门",
@@ -93,25 +77,5 @@
"user_team_invite_member": "邀请成员",
"user_team_leave_team": "离开团队",
"user_team_leave_team_failed": "离开团队失败",
"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}}】]"
"waiting": "待接受"
}

View File

@@ -97,7 +97,7 @@
"permission.des.read": "可查看知识库内容",
"permission.des.write": "可增加和变更知识库内容",
"preview_chunk": "分块预览",
"preview_chunk_empty": "文件内容为空",
"preview_chunk_empty": "无法读取该文件内容",
"preview_chunk_intro": "共 {{total}} 个分块,最多展示 10 个",
"preview_chunk_not_selected": "点击左侧文件后进行预览",
"process.Auto_Index": "自动索引生成",
@@ -125,7 +125,6 @@
"split_sign_question": "问号",
"split_sign_semicolon": "分号",
"start_sync_website_tip": "确认开始同步数据?将会删除旧数据后重新获取,请确认!",
"status_error": "运行异常",
"sync_collection_failed": "同步集合错误,请检查是否能正常访问源文件",
"sync_schedule": "定时同步",
"sync_schedule_tip": "仅会同步已存在的集合。包括链接集合以及 API 知识库里所有集合。系统会每天进行轮询更新,无法确定具体的更新时间。",

View File

@@ -98,9 +98,11 @@
"team.group.keep_admin": "保留管理员权限",
"team.group.manage_member": "管理成员",
"team.group.manage_tip": "可以管理成员、创建群组、管理所有群组、为群组和成员分配权限",
"team.group.permission_tip": "单独配置权限的成员,将遵循个人权限配置,不再受群组权限影响。\n若成员在多个权限组则该成员的权限取并集。",
"team.group.members": "成员",
"team.group.name": "群组名称",
"team.group.permission.manage": "管理员",
"team.group.permission.write": "工作台/知识库创建",
"team.group.permission_tip": "单独配置权限的成员,将遵循个人权限配置,不再受群组权限影响。\n若成员在多个权限组则该成员的权限取并集。",
"team.group.role.admin": "管理员",
"team.group.role.member": "成员",
"team.group.role.owner": "所有者",
@@ -110,6 +112,5 @@
"team.manage_collaborators": "管理协作者",
"team.no_collaborators": "暂无协作者",
"team.org.org": "部门",
"team.write_role_member": "可写权限",
"team.collaborator.added": "已添加"
"team.write_role_member": "可写权限"
}

View File

@@ -77,7 +77,6 @@
"ifelse.Input value": "输入值",
"ifelse.Select value": "选择值",
"input_description": "字段描述",
"input_type_multiple_select": "多选框",
"input_variable_list": "可输入 / 唤起变量列表",
"intro_assigned_reply": "该模块可以直接回复一段指定的内容。常用于引导、提示。非字符串内容传入时,会转成字符串进行输出。",
"intro_custom_feedback": "该模块被触发时,会给当前的对话记录增加一条反馈。可用于自动记录对话效果等。",
@@ -153,7 +152,6 @@
"response.read files": "解析的文档",
"select_an_application": "选择一个应用",
"select_another_application_to_call": "可以选择一个其他应用进行调用",
"select_default_option": "选择默认值",
"special_array_format": "特殊数组格式,搜索结果为空时,返回空数组。",
"start_with": "开始为",
"support_code_language": "支持import列表pandasnumpy",
@@ -203,4 +201,4 @@
"workflow.Switch_success": "切换成功",
"workflow.Team cloud": "团队云端",
"workflow.exit_tips": "您的更改尚未保存,「直接退出」将不会保存您的编辑记录。"
}
}

View File

@@ -3,30 +3,30 @@
"add_default_model": "新增預設模型",
"api_key": "API 金鑰",
"bills_and_invoices": "帳單與發票",
"channel": "模型道",
"config_model": "模型設定",
"confirm_logout": "確認登出登入",
"channel": "模型道",
"config_model": "模型配置",
"confirm_logout": "確認登出登入?",
"create_channel": "新增頻道",
"create_model": "新增模型",
"custom_model": "自訂模型",
"default_model": "預設模型",
"default_model_config": "預設模型設定",
"default_model_config": "預設模型配置",
"logout": "登出",
"model.active": "啟用",
"model.alias": "別名",
"model.alias_tip": "模型在系統中展示的名字,方便使用者理解",
"model.censor_tip": "如果需要進行敏感校驗,則開啟該開關",
"model.charsPointsPrice": "模型綜合價格",
"model.charsPointsPrice_tip": "將模型輸入和輸出合併起來進行 Token 計費,語言模型如果單獨設定了輸入和輸出計費,則按輸入和輸出分別計算",
"model.charsPointsPrice_tip": "將模型輸入和輸出合併起來進行 Token 計費,語言模型如果單獨配置了輸入和輸出計費,則按輸入和輸出分別計算",
"model.custom_cq_prompt": "自訂問題分類提示詞",
"model.custom_cq_prompt_tip": "覆蓋系統預設的問題分類提示詞,預設為:\n\"\"\"\n{{prompt}}\n\"\"\"",
"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.defaultConfig": "額外 Body 參數",
"model.defaultConfig_tip": "每次請求時候,都會攜帶該額外 Body 參數",
"model.default_config": "Body 額外欄位",
"model.default_config_tip": "發起對話請求時候,合併該設定。例如:\n\"\"\"\n{\n \"temperature\": 1,\n \"max_tokens\": null\n}\n\"\"\"",
"model.default_config": "Body 額外字段",
"model.default_config_tip": "發起對話請求時候,合併該配置。例如:\n\"\"\"\n{\n \"temperature\": 1,\n \"max_tokens\": null\n}\n\"\"\"",
"model.default_model": "預設模型",
"model.default_system_chat_prompt": "預設提示詞",
"model.default_system_chat_prompt_tip": "模型對話時,都會攜帶該預設提示詞",
@@ -34,35 +34,35 @@
"model.default_token_tip": "索引模型預設文字分塊的長度,必須小於最大上文",
"model.delete_model_confirm": "確認刪除該模型?",
"model.edit_model": "模型參數編輯",
"model.function_call": "支援函式呼叫",
"model.function_call_tip": "如果模型支援函式呼叫,則開啟該開關。\n工具呼叫優先權更高。",
"model.function_call": "支援函數調用",
"model.function_call_tip": "如果模型支援函數調用,則開啟該開關。\n工具呼叫優先權更高。",
"model.input_price": "模型輸入價格",
"model.input_price_tip": "語言模型輸入價格,如果設定了該項,則模型綜合價格會失效",
"model.input_price_tip": "語言模型輸入價格,如果配置了該項,則模型綜合價格會失效",
"model.json_config": "設定檔",
"model.json_config_confirm": "確認使用該設定進行覆蓋?",
"model.json_config_tip": "透過設定檔設定模型,點選確認後,會使用輸入的設定進行全量覆蓋,請確保設定檔輸入正確。\n建議操作前複製目前設定檔進行備份。",
"model.json_config_confirm": "確認使用該配置進行覆蓋?",
"model.json_config_tip": "透過設定檔設定模型,點選確認後,會使用輸入的配置進行全量覆蓋,請確保設定檔輸入正確。\n建議操作前複製目前設定檔進行備份。",
"model.max_quote": "知識庫最大引用",
"model.max_temperature": "最大溫度",
"model.model_id": "模型 ID",
"model.model_id_tip": "模型的唯一標識,也就是實際請求到服務商 model 的值,需要與 OneAPI 頻道中的模型對應。",
"model.model_id": "模型ID",
"model.model_id_tip": "模型的唯一標識也就是實際請求到服務商model 的值,需要與 OneAPI 頻道中的模型對應。",
"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_tip": "語言模型輸出價格,如果設定了該項,則模型綜合價格會失效",
"model.param_name": "參數名",
"model.reasoning": "支輸出思考",
"model.output_price_tip": "語言模型輸出價格,如果配置了該項,則模型綜合價格會失效",
"model.param_name": "參數名",
"model.reasoning": "支輸出思考",
"model.reasoning_tip": "例如 Deepseek-reasoner可以輸出思考過程。",
"model.request_auth": "自訂請求 Key",
"model.request_auth_tip": "向自訂請求地址發起請求時候攜帶請求頭Authorization: Bearer xxx 進行請求",
"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.show_stop_sign": "展示停止序列參數",
"model.show_top_p": "展示 Top-p 參數",
"model.test_model": "模型測試",
"model.tool_choice": "支援工具呼叫",
"model.tool_choice_tag": "工具呼叫",
"model.tool_choice_tip": "如果該模型支援工具呼叫,則開啟該開關",
"model.tool_choice": "支援工具調用",
"model.tool_choice_tag": "工具調用",
"model.tool_choice_tip": "如果該模型支援工具調用,則開啟該開關",
"model.used_in_classify": "用於問題分類",
"model.used_in_extract_fields": "用於文字擷取",
"model.used_in_tool_call": "用於工具呼叫節點",
@@ -70,14 +70,14 @@
"model.vision_tag": "視覺",
"model.vision_tip": "如果模型支援圖片識別,則開啟該開關。",
"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": "模型提供者",
"notifications": "通知",
"personal_information": "個人資訊",
"personalization": "個人化",
"promotion_records": "促銷記錄",
"reset_default": "恢復預設設定",
"reset_default": "恢復默認配置",
"team": "團隊管理",
"third_party": "第三方賬號",
"third_party": "第三方账号",
"usage_records": "使用記錄"
}

View File

@@ -3,7 +3,7 @@
"back": "返回",
"bank_account": "開戶帳號",
"bank_name": "開戶銀行",
"bill_detail": "帳單詳細資訊",
"bill_detail": "帳單詳",
"bill_record": "帳單記錄",
"company_address": "公司地址",
"company_phone": "公司電話",
@@ -12,15 +12,15 @@
"contact_phone": "聯絡電話",
"contact_phone_void": "聯絡電話格式錯誤",
"default_header": "預設抬頭",
"detail": "詳細資訊",
"detail": "詳",
"email_address": "郵件地址",
"extra_ai_points": "AI 積分運算標準",
"extra_dataset_size": "額外知識庫容量",
"generation_time": "生成時間",
"has_invoice": "是否已開票",
"invoice_amount": "開票金額",
"invoice_detail": "發票詳細資訊",
"invoice_sending_info": "發票將在 3-7 個工作天內送至郵箱,請耐心等待",
"invoice_detail": "發票詳",
"invoice_sending_info": "發票將在 3-7 個工作天內送至郵箱,請耐心等待",
"mm": "毫米",
"need_special_invoice": "是否需要專票",
"no": "否",
@@ -31,8 +31,8 @@
"organization_name": "組織名稱",
"payment_method": "支付方式",
"save": "儲存",
"save_failed": "存異常",
"save_success": "存成功",
"save_failed": "存異常",
"save_success": "存成功",
"status": "狀態",
"submit_failed": "提交失敗",
"submit_success": "提交成功",

View File

@@ -28,10 +28,10 @@
"exchange_success": "兌換成功",
"expiration_time": "到期時間",
"expired": "已過期",
"general_info": "通用資訊",
"general_info": "通用信息",
"group": "群組",
"help_chatbot": "機器人助手",
"help_document": "幫助文",
"help_document": "幫助文",
"knowledge_base_capacity": "知識庫容量",
"manage": "管理",
"member_name": "成員名",
@@ -39,36 +39,36 @@
"new_password": "新密碼",
"notification_receiving": "通知接收",
"old_password": "舊密碼",
"openai_account_configuration": "OpenAI 帳號設定",
"openai_account_configuration": "OpenAI 帳號配置",
"openai_account_setting_exception": "設定 OpenAI 帳號異常",
"package_and_usage": "套餐與用量",
"package_details": "套餐詳細資訊",
"package_details": "套餐詳",
"package_expiry_time": "套餐到期時間",
"package_usage_rules": "套餐使用規則:系統優先使用更進階的套餐,原未用完的套餐將延遲生效",
"password": "密碼",
"password_mismatch": "密碼不一致兩次密碼不一致",
"password_tip": "密碼至少 6 位,且至少包含兩種組合:數字、字母或特殊字",
"password_mismatch": "密碼不一致: 兩次密碼不一致",
"password_tip": "密碼至少 6 位,且至少包含兩種組合:數字、字母或特殊字",
"password_update_error": "修改密碼異常",
"password_update_success": "修改密碼成功",
"pending_usage": "待使用",
"phone_label": "手機號",
"please_bind_notification_receiving_path": "請先綁定通知接收途徑",
"purchase_extra_package": "購買額外套餐",
"reminder_create_bound_notification_account": "提醒建者綁定通知帳號",
"reminder_create_bound_notification_account": "提醒建者綁定通知帳號",
"resource_usage": "資源用量",
"select_avatar": "點選選擇頭像",
"standard_package_and_extra_resource_package": "包含標準套餐與額外資源包",
"storage_capacity": "儲存量",
"team_balance": "團隊餘額",
"team_info": "團隊資訊",
"team_info": "團隊信息",
"token_validity_period": "積分有效期限一年",
"tokens": "積分",
"type": "類型",
"unlimited": "無限制",
"update_password": "修改密碼",
"update_success_tip": "更新資料成功",
"update_success_tip": "更新數據成功",
"upgrade_package": "升級套餐",
"usage_balance": "使用餘額使用餘額",
"usage_balance": "使用餘額: 使用餘額",
"usage_balance_notice": "由於系統升級,原「自動續費從餘額扣款」模式取消,餘額儲值入口關閉。\n您的餘額可用於購買積分",
"user_account": "帳號",
"user_team_team_name": "團隊",

View File

@@ -1,5 +1,5 @@
{
"notification_detail": "通知詳細資訊",
"notification_detail": "通知詳",
"no_notifications": "暫無通知",
"read": "已讀",
"system": "官方",

View File

@@ -1,52 +1,52 @@
{
"Hunyuan": "騰訊混元",
"api_key": "API 鑰",
"api_key": "API 鑰",
"azure": "Azure",
"base_url": "代理地址",
"channel_name": "道名",
"channel_priority": "優先順序",
"channel_priority_tip": "優先順序越高的道,越容易被請求到",
"channel_name": "道名",
"channel_priority": "優先",
"channel_priority_tip": "優先越高的道,越容易被請求到",
"channel_status": "狀態",
"channel_status_auto_disabled": "自動用",
"channel_status_disabled": "用",
"channel_status_auto_disabled": "自動用",
"channel_status_disabled": "用",
"channel_status_enabled": "啟用",
"channel_status_unknown": "未知",
"channel_type": "廠商",
"clear_model": "清空模型",
"confirm_delete_channel": "確認刪除【{{name}}】道?",
"copy_model_id_success": "已復制模型 id",
"create_channel": "新增道",
"default_url": "預設地址",
"detail": "詳細資訊",
"edit_channel": "管道設定",
"confirm_delete_channel": "確認刪除 【{{name}}】道?",
"copy_model_id_success": "已復制模型id",
"create_channel": "新增道",
"default_url": "默認地址",
"detail": "詳",
"edit_channel": "渠道配置",
"enable_channel": "啟用",
"forbid_channel": "用",
"key_type": "API key 格式",
"log": "呼叫日誌",
"log_detail": "日誌詳細資訊",
"log_request_id_search": "根據 requestId 搜",
"forbid_channel": "用",
"key_type": "API key 格式:",
"log": "調用日誌",
"log_detail": "日誌詳",
"log_request_id_search": "根據 requestId 搜",
"log_status": "狀態",
"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。",
"maxToken_tip": "模型 max_tokens 參數,如果留空,則代表模型不支該參數。",
"max_temperature_tip": "模型 temperature 參數,不填則代表模型不支 temperature 參數。",
"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。",
"maxToken_tip": "模型 max_tokens 參數,如果留空,則代表模型不支該參數。",
"max_temperature_tip": "模型 temperature 參數,不填則代表模型不支 temperature 參數。",
"model": "模型",
"model_name": "模型名",
"model_test": "模型測試",
"model_tokens": "輸入/輸出 Tokens",
"request_at": "請求時間",
"request_duration": "請求時長{{duration}}s",
"request_duration": "請求時長: {{duration}}s",
"retry_times": "重試次數",
"running_test": "測試中",
"search_model": "搜模型",
"select_channel": "選擇道名",
"search_model": "搜模型",
"select_channel": "選擇道名",
"select_model": "選擇模型",
"select_model_placeholder": "選擇該道下可用的模型",
"select_provider_placeholder": "搜廠商",
"select_model_placeholder": "選擇該道下可用的模型",
"select_provider_placeholder": "搜廠商",
"selected_model_empty": "至少選擇一個模型",
"start_test": "批測試{{num}}個模型",
"start_test": "批測試{{num}}個模型",
"test_failed": "有{{num}}個模型報錯",
"vlm_model": "圖片理解模型",
"vlm_model_tip": "用於知識庫中對文中的圖片進行額外的索引生成",
"vlm_model_tip": "用於知識庫中對文中的圖片進行額外的索引生成",
"waiting_test": "等待測試"
}

View File

@@ -5,7 +5,7 @@
"copy_invite_link": "複製邀請連結",
"earnings": "收益(¥)",
"invite_url": "邀請連結",
"invite_url_tip": "透過該連結註冊的好友將永久與你綁定,其儲值時你會獲得一定餘額獎勵。\n \n此外好友使用手機號碼註冊時你將立即獲得 5 元獎勵。\n \n獎勵會送到您的預設團隊。",
"invite_url_tip": "透過該連結註冊的好友將永久與你綁定,其儲值時你會獲得一定餘額獎勵。\n \n此外好友使用手機號碼註冊時你將立即獲得 5 元獎勵。\n \n獎勵會送到您的預設團隊。",
"no_invite_records": "暫無邀請紀錄",
"time": "時間",
"total_invited": "累計邀請人數",

View File

@@ -2,5 +2,5 @@
"language": "語言",
"personalization": "個人化",
"timezone": "時區",
"update_data_success": "更新資料成功"
"update_data_success": "更新數據成功"
}

View File

@@ -1,34 +1,28 @@
{
"1person": "1 人",
"1year": "1 年",
"30mins": "30 分鐘",
"7days": "7 天",
"1person": "1人",
"1year": "1年",
"30mins": "30分鐘",
"7days": "7天",
"accept": "接受",
"action": "操作",
"assign_permission": "權限變更",
"change_department_name": "部門編輯",
"change_member_name": "成員改名",
"confirm_delete_group": "確認刪除群組?",
"confirm_delete_member": "確認刪除成員?",
"confirm_delete_org": "確認刪除該部門?",
"confirm_forbidden": "確認停用",
"confirm_leave_team": "確認離開該團隊? \n結束後,您在該團隊所有的資源轉讓給團隊所有者。",
"confirm_leave_team": "確認離開該團隊? \n退出後,您在該團隊所有的資源轉讓給團隊所有者。",
"copy_link": "複製連結",
"create_department": "創建子部門",
"create_group": "建立群組",
"create_invitation_link": "建立邀請連結",
"create_org": "建部門",
"create_sub_org": "建子部門",
"create_org": "建部門",
"create_sub_org": "建子部門",
"delete": "刪除",
"delete_department": "刪除子部門",
"delete_group": "刪除群組",
"delete_org": "刪除部門",
"edit_info": "編輯訊息",
"edit_member": "編輯使用者",
"edit_member": "編輯用戶",
"edit_member_tip": "成員名",
"edit_org_info": "編輯部門資訊",
"expires": "過期時間",
"forbid_hint": "停用後,該邀請連結將失效。該操作不可撤銷,是否確認停用?",
"forbid_hint": "停用後,該邀請連結將失效。 該操作不可撤銷,是否確認停用?",
"forbid_success": "停用成功",
"forbidden": "停用",
"group": "群組",
@@ -38,56 +32,26 @@
"has_invited": "已邀請",
"ignore": "忽略",
"invitation_copy_link": "【{{systemName}}】 {{userName}} 邀請您加入{{teamName}}團隊,連結:{{url}}",
"invitation_link_auto_clean_hint": "已失效連結將在 30 天後自動清理",
"invitation_link_auto_clean_hint": "已失效連結將在30天後自動清理",
"invitation_link_description": "連結描述",
"invitation_link_list": "連結列表",
"invite_member": "邀請成員",
"invited": "已邀請",
"join_team": "加入團隊",
"kick_out_team": "移除成員",
"label_sync": "標籤同步",
"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": "管理成員",
"member": "成員",
"member_group": "所屬成員組",
"move_member": "移動成員",
"move_org": "行動部門",
"operation_log": "紀錄",
"org": "組織",
"org_description": "介紹",
"org_name": "部門名稱",
"owner": "擁有者",
"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": "備註",
"remove_tip": "確認將 {{username}} 移出團隊?",
"retain_admin_permissions": "保留管理員權限",
"search_log": "搜索日誌",
"search_member_group_name": "搜尋成員/群組名稱",
"total_team_members": "共 {{amount}} 名成員",
"transfer_ownership": "轉讓所有者",

View File

@@ -1,16 +1,16 @@
{
"configured": "已設定",
"error.no_permission": "請聯管理員設定",
"configured": "已配置",
"error.no_permission": "請聯管理員配置",
"laf_account": "af 帳號",
"no_intro": "暫無說明",
"not_configured": "未設定",
"open_api_notice": "可以填寫 OpenAI/OneAPI 的相關金鑰。\n如果你填寫了該內容在線上平使用【AI 對話】、【問題分類】和【內容提取】將會走你填寫的 Key不會計費用。\n請注意你的 Key 是否有存取對應模型的權限。 \nGPT 模型可以選擇 FastAI。",
"not_configured": "未配置",
"open_api_notice": "可以填寫 OpenAI/OneAPI 的相關金鑰。\n如果你填寫了該內容在線上平使用【 AI 對話】、【問題分類】和【內容提取】將會走你填寫的 Key不會計費用。\n請注意你的 Key 是否有存取對應模型的權限。 \nGPT 模型可以選擇 FastAI 。",
"openai_account_configuration": "OpenAI/OneAPI 帳號",
"request_address_notice": "請求地址,預設為 openai 官方。可填中轉位址,未自動補全 \"v1\"",
"third_party_account": "第三方帳號",
"third_party_account_desc": "管理員可以在這裡設定第三方帳號或變,該帳號將被團隊所有人使用",
"third_party_account_desc": "管理員可以在這裡配置第三方帳號或變,該帳號將被團隊所有人使用",
"unavailable": "取得使用量異常",
"usage": "使用量:",
"value_not_return_tip": "參數設定後,不會再次返回前端,無需洩漏給其他成員",
"value_placeholder": "輸入參數值。\n輸入空值表示刪除該設定。"
"value_not_return_tip": "參數配置後,不會再次返回前端,無需洩漏給其他成員",
"value_placeholder": "輸入參數值。\n輸入空值表示刪除該配置。"
}

View File

@@ -4,17 +4,17 @@
"app_name": "應用程式名",
"auto_index": "索引增強",
"billing_module": "扣費模組",
"confirm_export": "共篩選出 {{total}} 條資料,是否確認出?",
"current_filter_conditions": "前篩選條件:",
"confirm_export": "共篩選出 {{total}} 條數據,是否確認出?",
"current_filter_conditions": "前篩選條件:",
"dashboard": "儀表板",
"details": "詳細資訊",
"details": "詳",
"dingtalk": "釘釘",
"duration_seconds": "時長(秒)",
"embedding_index": "索引生成",
"every_day": "天",
"every_month": "月",
"export_confirm": "出確認",
"export_confirm_tip": "前共 {{total}} 筆使用記錄,確認出?",
"export_confirm": "出確認",
"export_confirm_tip": "前共 {{total}} 筆使用記錄,確認出?",
"export_title": "時間,成員,類型,項目名,AI 積分消耗",
"feishu": "飛書",
"generation_time": "生成時間",
@@ -42,7 +42,7 @@
"total_points": "AI 積分消耗",
"total_points_consumed": "AI 積分消耗",
"total_usage": "總消耗",
"usage_detail": "使用詳細資訊",
"usage_detail": "使用詳",
"user_type": "類型",
"wecom": "企業微信"
}

View File

@@ -3,16 +3,16 @@
"Run": "執行",
"Team Tags Set": "團隊標籤",
"Team_Tags": "團隊標籤",
"ai_point_price": "AI 積分計費",
"ai_point_price": "AI積分計費",
"ai_settings": "AI 設定",
"all_apps": "所有應用程式",
"app.Version name": "版本名稱",
"app.error.publish_unExist_app": "發布失敗,請檢查工具呼叫是否正常",
"app.error.unExist_app": "部分元件遺失,請刪除",
"app.error.publish_unExist_app": "發布失敗,請檢查工具調用是否正常",
"app.error.unExist_app": "部分組件缺失,請刪除",
"app.modules.click to update": "點選更新",
"app.modules.has new version": "有新版本",
"app.modules.not_found": "元件遺失",
"app.modules.not_found_tips": "系統內無法查到該件,請刪除,否則流程無法正常運",
"app.modules.not_found": "組件缺失",
"app.modules.not_found_tips": "系統內無法查到該件,請刪除,否則流程無法正常運",
"app.version_current": "目前版本",
"app.version_initial": "初始版本",
"app.version_name_tips": "版本名稱不能空白",
@@ -20,23 +20,23 @@
"app.version_publish_tips": "此版本將儲存至團隊雲端,同步給整個團隊,同時更新所有發布通道的應用程式版本",
"app_detail": "應用程式詳細資訊",
"auto_execute": "自動執行",
"auto_execute_default_prompt_placeholder": "自動執行時,送的預設問題",
"auto_execute_default_prompt_placeholder": "自動執行時,送的預設問題",
"auto_execute_tip": "開啟後,使用者進入對話式介面將自動觸發工作流程。\n執行順序1、對話開場白2、全域變數3、自動執行。",
"auto_save": "自動儲存",
"chat_debug": "聊天預覽",
"chat_logs": "對話紀錄",
"chat_logs_tips": "紀錄會記錄此應用程式的線上、分享和 API需填寫 chatId對話紀錄",
"config_ai_model_params": "點選設定 AI 模型相關屬性",
"config_ai_model_params": "點選配置 AI 模型相關屬性",
"config_file_upload": "點選設定檔案上傳規則",
"config_question_guide": "設定猜你想問",
"config_question_guide": "配置猜你想問",
"confirm_copy_app_tip": "系統將為您建立一個相同設定的應用程式,但權限不會複製,請確認!",
"confirm_del_app_tip": "確認刪除【{{name}}】及其所有聊天紀錄?",
"confirm_delete_folder_tip": "確認刪除這個資料夾?將會刪除它底下所有應用程式及對應的對話紀錄,請確認!",
"copy_one_app": "建立副本",
"core.app.QG.Switch": "啟用猜你想問",
"core.dataset.import.Custom prompt": "自訂提示詞",
"create_by_curl": "從 CURL 建",
"create_by_template": "從範本建立",
"create_by_curl": "從 CURL 建",
"create_by_template": "從模板創建",
"create_copy_success": "建立副本成功",
"create_empty_app": "建立空白應用程式",
"create_empty_plugin": "建立空白外掛",
@@ -74,22 +74,22 @@
"interval.4_hours": "每 4 小時",
"interval.6_hours": "每 6 小時",
"interval.per_hour": "每小時",
"intro": "FastGPT 是一個基於大型語言模型的知識庫平臺,提供開箱即用的資料處理、向量檢索和視覺化 AI 工作流程編排等功能,讓您可以輕鬆開發和部署複雜的問答系統,而無需繁瑣的設定或設定。",
"intro": "FastGPT 是一個基於大型語言模型的知識庫平臺,提供開箱即用的資料處理、向量檢索和視覺化 AI 工作流程編排等功能,讓您可以輕鬆開發和部署複雜的問答系統,而無需繁瑣的設定或配置。",
"invalid_json_format": "JSON 格式錯誤",
"llm_not_support_vision": "這個模型不支援圖片辨識",
"llm_use_vision": "圖片辨識",
"llm_use_vision_tip": "點選模型選擇後,可以看到模型是否支援圖片辨識以及控制是否啟用圖片辨識的功能。啟用圖片辨識後,模型會讀取檔案連結中的圖片內容,並且如果使用者問題少於 500 字,會自動解析使用者問題中的圖片。",
"logs_chat_user": "使用者",
"logs_empty": "還沒有紀錄喔~",
"logs_export_confirm_tip": "前共 {{total}} 條對話記錄,確認出?",
"logs_export_title": "時間,來源,使用者,聯方式,標題,息總數,使用者贊同饋,使用者反對饋,自定義饋,標註答案,對話詳細資訊",
"logs_export_confirm_tip": "前共 {{total}} 條對話記錄,確認出?",
"logs_export_title": "時間,來源,使用者,聯方式,標題,息總數,用戶贊同饋,用戶反對饋,自定義饋,標註答案,對話詳",
"logs_message_total": "訊息總數",
"logs_source": "源",
"logs_source": "源",
"logs_title": "標題",
"look_ai_point_price": "檢視所有模型計費標準",
"look_ai_point_price": "查看所有模型計費標準",
"mark_count": "標記答案數量",
"max_histories_number": "記憶輪數",
"max_histories_number_tip": "模型最多攜帶多少輪對話進入記憶中,如果記憶超出模型上下文,系統會強制截斷。\n所以儘管設定 30 輪對話,實際運時候,不一定會達到 30 輪。",
"max_histories_number_tip": "模型最多攜帶多少輪對話進入記憶中,如果記憶超出模型上下文,系統會強制截斷。\n所以儘管配置 30 輪對話,實際運時候,不一定會達到 30 輪。",
"max_tokens": "回覆上限",
"module.Custom Title Tip": "這個標題會顯示在對話過程中",
"module.No Modules": "找不到外掛",
@@ -104,10 +104,10 @@
"open_auto_execute": "啟用自動執行",
"open_vision_function_tip": "有圖示開關的模型即擁有圖片辨識功能。若開啟,模型會解析檔案連結中的圖片,並自動解析使用者問題中的圖片(使用者問題 ≤ 500 字時生效)。",
"or_drag_JSON": "或拖曳 JSON 檔案",
"paste_config_or_drag": "貼上設定或拖入 JSON 文件",
"pdf_enhance_parse": "PDF 增強解析",
"paste_config_or_drag": "貼上配置或拖入 JSON 文件",
"pdf_enhance_parse": "PDF增強解析",
"pdf_enhance_parse_price": "{{price}}積分/頁",
"pdf_enhance_parse_tips": "呼叫 PDF 識別模型進行解析,可以將其轉換成 Markdown 並保留文中的圖片,同時也可以對掃描件進行識別,識別時間較長。",
"pdf_enhance_parse_tips": "調用 PDF 識別模型進行解析,可以將其轉換成 Markdown 並保留文中的圖片,同時也可以對掃描件進行識別,識別時間較長。",
"permission.des.manage": "在寫入權限基礎上,可以設定發布通道、檢視對話紀錄、分配這個應用程式的權限",
"permission.des.read": "可以使用這個應用程式進行對話",
"permission.des.write": "可以檢視和編輯應用程式",
@@ -120,16 +120,16 @@
"publish_success": "發布成功",
"question_guide_tip": "對話結束後,會為你產生 3 個引導性問題。",
"reasoning_response": "輸出思考",
"response_format": "回格式",
"saved_success": "存成功!\n如需在外部使用該版本請點“儲存並發布”",
"response_format": "回格式",
"saved_success": "存成功!\n如需在外部使用該版本請點“儲存並發布”",
"search_app": "搜尋應用程式",
"setting_app": "應用程式設定",
"setting_plugin": "外掛設定",
"show_top_p_tip": "用溫度樣的替代方法,稱為 Nucleus樣,該模型考慮了具有 TOP_P率質量質量的令牌的結果。\n因此0.1 表示僅考慮包含最高率質量的令牌。\n預設為 1。",
"simple_tool_tips": "該外掛含有特殊輸入,暫不支被簡易應用呼叫",
"show_top_p_tip": "用溫度樣的替代方法稱為Nucleus該模型考慮了具有TOP_P率質量質量的令牌的結果。\n因此0.1表示僅考慮包含最高率質量的令牌。\n默認為 1。",
"simple_tool_tips": "該插件含有特殊輸入,暫不支被簡易應用調用",
"source_updateTime": "更新時間",
"stop_sign": "停止序列",
"stop_sign_placeholder": "多個序列號過 | 隔開例如aaa|stop",
"stop_sign_placeholder": "多個序列號過 | 隔開例如aaa|stop",
"stream_response": "流輸出",
"stream_response_tip": "關閉該開關​​,可以強制模型使用非流模式,並且不會直接進行內容輸出。\n可在 AI 回覆的輸出中,取得本次模型輸出的內容進行二次處理。",
"temperature": "溫度",
@@ -152,7 +152,7 @@
"templateMarket.templateTags.Roleplay": "角色扮演",
"templateMarket.templateTags.Web_search": "網路搜尋",
"templateMarket.templateTags.Writing": "文字創作",
"templateMarket.template_guide": "範本說明",
"templateMarket.template_guide": "模板說明",
"template_market": "範本市集",
"template_market_description": "在範本市集探索更多玩法,設定教學與使用指引,帶您理解並上手各種應用程式",
"template_market_empty_data": "找不到合適的範本",
@@ -162,7 +162,7 @@
"transition_to_workflow_create_new_placeholder": "建立新的應用程式,而不是修改目前應用程式",
"transition_to_workflow_create_new_tip": "轉換成工作流程後,將無法轉換回簡易模式,請確認!",
"tts_ai_model": "使用語音合成模型",
"tts_browser": "瀏覽器自帶 (免費)",
"tts_browser": "瀏覽器自帶(免費)",
"tts_close": "關閉",
"type.All": "全部",
"type.Create http plugin tip": "透過 OpenAPI Schema 批次建立外掛,相容 GPTs 格式",
@@ -173,7 +173,7 @@
"type.Create workflow bot": "建立工作流程",
"type.Create workflow tip": "透過低程式碼的方式,建立邏輯複雜的多輪對話 AI 應用程式,建議進階使用者使用",
"type.Http plugin": "HTTP 外掛",
"type.Import from json": "入 JSON 設定",
"type.Import from json": "入 JSON 配置",
"type.Import from json tip": "透過 JSON 設定文件,直接建立應用",
"type.Plugin": "外掛",
"type.Simple bot": "簡易應用程式",

View File

@@ -5,20 +5,20 @@
"ai_reasoning": "思考過程",
"back_to_text": "返回輸入",
"chat.quote.No Data": "找不到該文件",
"chat.quote.deleted": "該資料已被刪除~",
"chat.quote.deleted": "該數據已被刪除~",
"chat_history": "對話紀錄",
"chat_input_guide_lexicon_is_empty": "尚未設定詞彙庫",
"chat_test_app": "除錯-{{name}}",
"chat_test_app": "調試-{{name}}",
"citations": "{{num}} 筆引用",
"click_contextual_preview": "點選檢視上下文預覽",
"completion_finish_close": "連接斷開",
"completion_finish_content_filter": "觸發安全風控",
"completion_finish_function_call": "函式呼叫",
"completion_finish_length": "超出回限制",
"completion_finish_function_call": "函數調用",
"completion_finish_length": "超出回限制",
"completion_finish_null": "未知",
"completion_finish_reason": "完成原因",
"completion_finish_stop": "正常完成",
"completion_finish_tool_calls": "工具呼叫",
"completion_finish_tool_calls": "工具調用",
"config_input_guide": "設定輸入導引",
"config_input_guide_lexicon": "設定詞彙庫",
"config_input_guide_lexicon_title": "設定詞彙庫",
@@ -27,10 +27,10 @@
"contextual_preview": "上下文預覽 {{num}} 筆",
"csv_input_lexicon_tip": "僅支援 CSV 批次匯入,點選下載範本",
"custom_input_guide_url": "自訂詞彙庫網址",
"data_source": "來源知識庫{{name}}",
"data_source": "來源知識庫: {{name}}",
"dataset_quote_type error": "知識庫引用類型錯誤,正確類型:{ datasetId: string }[]",
"delete_all_input_guide_confirm": "確定要清除輸入導引詞彙庫嗎?",
"download_chunks": "下載資料",
"download_chunks": "下載數據",
"empty_directory": "此目錄中已無項目可選~",
"file_amount_over": "超出檔案數量上限 {{max}}",
"file_input": "檔案輸入",
@@ -52,12 +52,12 @@
"not_select_file": "尚未選取檔案",
"plugins_output": "外掛程式輸出",
"press_to_speak": "按住說話",
"query_extension_IO_tokens": "問題最佳化輸入/輸出 Tokens",
"query_extension_IO_tokens": "問題化輸入/輸出 Tokens",
"question_tip": "由上至下,各個模組的回應順序",
"read_raw_source": "開原文",
"read_raw_source": "開原文",
"reasoning_text": "思考過程",
"release_cancel": "鬆開取消",
"release_send": "鬆開送,上滑取消",
"release_send": "鬆開送,上滑取消",
"response.child total points": "子工作流程點數消耗",
"response.dataset_concat_length": "合併總數",
"response.node_inputs": "節點輸入",
@@ -72,7 +72,7 @@
"to_dataset": "前往知識庫",
"unsupported_file_type": "不支援的檔案類型",
"upload": "上傳",
"variable_invisable_in_share": "自定義變在免登入連結中不可見",
"variable_invisable_in_share": "自定義變在免登錄鏈接中不可見",
"view_citations": "檢視引用",
"web_site_sync": "網站同步"
}

View File

@@ -1,10 +1,10 @@
{
"App": "應用程式",
"Click_to_expand": "點選檢視詳細資訊",
"Click_to_expand": "點擊查看詳情",
"Download": "下載",
"Export": "匯出",
"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_q": "什麼是 AI 點數?",
"FAQ.check_subscription_a": "帳號 - 個人資訊 - 方案詳細資訊 - 使用狀況。您可以檢視已訂閱方案的生效和到期時間。當付費方案到期後,將自動切換為免費版。",
@@ -46,7 +46,7 @@
"click_to_resume": "點選繼續",
"code_editor": "程式碼編輯器",
"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_owner": "非法的應用程式擁有者",
"code_error.app_error.not_exist": "應用程式不存在",
@@ -90,7 +90,7 @@
"code_error.team_error.group_name_duplicate": "群組名稱重複",
"code_error.team_error.group_name_empty": "群組名稱不能為空",
"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.org_member_duplicated": "重複的組織成員",
"code_error.team_error.org_member_not_exist": "組織成員不存在",
@@ -102,7 +102,7 @@
"code_error.team_error.too_many_invitations": "您的有效邀請連結數已達上限,請先清理連結",
"code_error.team_error.un_auth": "無權操作此團隊",
"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.token_error_code.403": "登入狀態無效,請重新登入",
"code_error.user_error.balance_not_enough": "帳戶餘額不足",
@@ -118,7 +118,7 @@
"common.Cancel": "取消",
"common.Choose": "選擇",
"common.Close": "關閉",
"common.Code": "原始碼",
"common.Code": "碼",
"common.Config": "設定",
"common.Confirm": "確認",
"common.Confirm Create": "確認建立",
@@ -291,7 +291,7 @@
"core.app.Chat Variable": "對話變數",
"core.app.Config schedule plan": "設定排程執行",
"core.app.Config whisper": "設定語音輸入",
"core.app.Config_auto_execute": "點選設定自動執行規則",
"core.app.Config_auto_execute": "點選配置自動執行規則",
"core.app.Interval timer config": "排程執行設定",
"core.app.Interval timer run": "排程執行",
"core.app.Interval timer tip": "可排程執行應用程式",
@@ -304,7 +304,7 @@
"core.app.QG.Custom prompt tip1": "為確保生成的內容遵循正確格式,",
"core.app.QG.Custom prompt tip2": "【黃色部分提示詞】",
"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.Quote prompt": "引用範本提示詞",
"core.app.Quote templates": "引用內容範本",
@@ -373,7 +373,7 @@
"core.app.tip.Add a intro to app": "快來為應用程式寫一個介紹",
"core.app.tip.chatNodeSystemPromptTip": "在此輸入提示詞",
"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.tool_label.doc": "使用文件",
"core.app.tool_label.github": "GitHub 網址",
@@ -452,7 +452,7 @@
"core.chat.markdown.Edit Question": "編輯問題",
"core.chat.markdown.Quick Question": "點我立即發問",
"core.chat.markdown.Send Question": "傳送問題",
"core.chat.module_unexist": "行失敗:應用遺失元件",
"core.chat.module_unexist": "行失敗:應用缺失組件",
"core.chat.quote.Quote Tip": "此處僅顯示實際引用內容,若資料有更新,此處不會即時更新",
"core.chat.quote.Read Quote": "檢視引用",
"core.chat.quote.afterUpdate": "更新後",
@@ -625,10 +625,10 @@
"core.dataset.search.score.reRank desc": "透過重新排名模型計算句子之間的關聯度,範圍為 0 到 1。",
"core.dataset.search.score.rrf": "綜合排名",
"core.dataset.search.score.rrf desc": "使用倒數排名融合方法,合併多個搜尋結果。",
"core.dataset.search.search mode": "搜方式",
"core.dataset.search.search mode": "搜方式",
"core.dataset.status.active": "已就緒",
"core.dataset.status.syncing": "同步中",
"core.dataset.status.waiting": "排中",
"core.dataset.status.waiting": "排中",
"core.dataset.test.Batch test": "批次測試",
"core.dataset.test.Batch test Placeholder": "選擇一個 CSV 檔案",
"core.dataset.test.Search Test": "搜尋測試",
@@ -644,7 +644,7 @@
"core.dataset.training.Agent queue": "問答訓練排隊中",
"core.dataset.training.Auto mode": "補充索引",
"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.Leisure": "閒置",
"core.dataset.training.QA mode": "問答對提取",
@@ -689,7 +689,7 @@
"core.module.Variable": "全域變數",
"core.module.Variable Setting": "變數設定",
"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.Enum Description": "列舉此欄位可能的值,每行一個",
"core.module.extract.Enum Value": "列舉值",
@@ -743,7 +743,7 @@
"core.module.template.AI support tool tip": "支援函式呼叫的模型可以更好地使用工具呼叫。",
"core.module.template.Basic Node": "基本功能",
"core.module.template.Query extension": "問題最佳化",
"core.module.template.System Plugin": "系統外掛",
"core.module.template.System Plugin": "系統插件",
"core.module.template.System input module": "系統輸入模組",
"core.module.template.Team app": "團隊應用程式",
"core.module.template.Tool module": "工具",
@@ -781,7 +781,7 @@
"core.view_chat_detail": "檢視對話詳細資料",
"core.workflow.Can not delete node": "此節點不允許刪除",
"core.workflow.Change input type tip": "修改輸入類型將清空已填寫的值,請確認!",
"core.workflow.Check Failed": "工作流校驗失敗,請檢查是否失、缺值,連線是否正常",
"core.workflow.Check Failed": "工作流校驗失敗,請檢查是否失、缺值,連線是否正常",
"core.workflow.Confirm stop debug": "確認停止除錯?除錯資訊將不會保留。",
"core.workflow.Copy node": "已複製節點",
"core.workflow.Custom inputs": "自訂輸入",
@@ -826,14 +826,14 @@
"core.workflow.template.Interactive": "互動",
"core.workflow.template.Multimodal": "多模態",
"core.workflow.template.Search": "搜尋",
"core.workflow.tool.Handle": "工具聯結器",
"core.workflow.tool.Handle": "工具連接器",
"core.workflow.tool.Select Tool": "選擇工具",
"core.workflow.value": "值",
"core.workflow.variable": "變數",
"create": "建立",
"cron_job_run_app": "排程任務",
"data_index_custom": "自定義索引",
"data_index_default": "預設索引",
"data_index_default": "默認索引",
"data_index_image": "圖片索引",
"data_index_question": "推測問題索引",
"data_index_summary": "摘要索引",
@@ -879,25 +879,25 @@
"dataset_data_input_chunk_content": "內容",
"dataset_data_input_q": "問題",
"dataset_data_input_qa": "QA 模式",
"dataset_text_model_tip": "用於知識庫預處理階段的文處理,例如自動補充索引、問答對提取。",
"deep_rag_search": "深度搜",
"dataset_text_model_tip": "用於知識庫預處理階段的文處理,例如自動補充索引、問答對提取。",
"deep_rag_search": "深度搜",
"delete_api": "確認刪除此 API 金鑰?\n刪除後該金鑰將立即失效對應的對話記錄不會被刪除請確認",
"embedding_model_not_config": "測到沒有可用的索引模型",
"embedding_model_not_config": "測到沒有可用的索引模型",
"error.Create failed": "建立失敗",
"error.code_error": "驗證碼錯誤",
"error.fileNotFound": "找不到檔案",
"error.inheritPermissionError": "繼承權限錯誤",
"error.invalid_params": "參數無效",
"error.missingParams": "參數不足",
"error.send_auth_code_too_frequently": "請勿頻繁取驗證碼",
"error.send_auth_code_too_frequently": "請勿頻繁取驗證碼",
"error.too_many_request": "請求太頻繁了,請稍後重試",
"error.upload_file_error_filename": "{{name}} 上傳失敗",
"error.upload_image_error": "上傳文件失敗",
"error.username_empty": "帳號不能為空",
"error_collection_not_exist": "集合不存在",
"error_embedding_not_config": "未設定索引模型",
"error_llm_not_config": "未設定文件理解模型",
"error_vlm_not_config": "未設定圖片理解模型",
"error_embedding_not_config": "未配置索引模型",
"error_llm_not_config": "未配置文件理解模型",
"error_vlm_not_config": "未配置圖片理解模型",
"extraction_results": "提取結果",
"field_name": "欄位名稱",
"free": "免費",
@@ -913,7 +913,7 @@
"info.include": "包含標準方案與額外資源包",
"info.node_info": "調整此模組會影響工具呼叫的時機。\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.resource": "資源使用量",
"invalid_variable": "無效變數",
@@ -923,7 +923,7 @@
"item_name": "欄位名稱",
"just_now": "剛剛",
"key_repetition": "鍵值重複",
"llm_model_not_config": "測到沒有可用的語言模型",
"llm_model_not_config": "測到沒有可用的語言模型",
"max_quote_tokens": "引用上限",
"max_quote_tokens_tips": "單次搜尋最大的 token 數量,中文約 1 字=1.7 tokens英文約 1 字=1 token",
"min_similarity": "最低相關度",
@@ -964,14 +964,14 @@
"new_create": "建立新項目",
"no": "否",
"no_laf_env": "系統未設定 LAF 環境",
"not_model_config": "未設定相關模型",
"not_model_config": "未配置相關模型",
"not_yet_introduced": "暫無介紹",
"option": "選項",
"pay.amount": "金額",
"pay.package_tip.buy": "您購買的方案等級低於目前方案,該方案將在目前方案過期後生效。\n您可在帳戶 - 個人資訊 - 方案詳細資訊中檢視方案使用情況。",
"pay.package_tip.renewal": "您正在續約方案。您可在帳戶 - 個人資訊 - 方案詳細資訊中檢視方案使用情況。",
"pay.package_tip.upgrade": "您購買的方案等級高於目前方案,該方案將立即生效,目前方案將延後生效。您可在帳戶 - 個人資訊 - 方案詳細資訊中檢視方案使用情況。",
"pay.wechat": "請微信掃碼付款{{price}}元\n\n付款完成前請勿關閉頁面",
"pay.wechat": "請微信掃碼付款: {{price}}元\n\n付款完成前請勿關閉頁面",
"pay.yuan": "{{amount}} 元",
"permission.Collaborator": "協作者",
"permission.Default permission": "預設權限",
@@ -1022,7 +1022,7 @@
"plugin.path": "路徑",
"prompt_input_placeholder": "請輸入提示詞",
"question_feedback": "工單諮詢",
"read_quote": "檢視引用",
"read_quote": "查看引用",
"required": "必填",
"rerank_weight": "重排權重",
"resume_failed": "恢復失敗",
@@ -1040,7 +1040,7 @@
"support.outlink.Max usage points tip": "此連結最多允許使用多少點數,超出後將無法使用。-1 代表無限制。",
"support.outlink.Usage points": "點數消耗",
"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 tips": "在分享連結中回傳引用內容,但不允許使用者下載原始文件",
"support.outlink.share.running_node": "執行節點",
@@ -1090,8 +1090,8 @@
"support.user.team.Team Tags Async Success": "同步完成",
"support.user.team.member": "成員",
"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_output": "輸出:{{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.Amount": "金額",
"support.wallet.App_amount_not_sufficient": "您的應用數量已達上限,請升級套餐後繼續使用。",
"support.wallet.Buy": "購買",

View File

@@ -4,7 +4,7 @@
"api_file": "API 檔案庫",
"api_url": "介面位址",
"auto_indexes": "自動生成補充索引",
"auto_indexes_tips": "過大模型進行額外索引生成,提高語義豐富度,提高檢索的精度。",
"auto_indexes_tips": "過大模型進行額外索引生成,提高語義豐富度,提高檢索的精度。",
"auto_training_queue": "增強索引排隊",
"chunk_max_tokens": "分塊上限",
"chunk_size": "分塊大小",
@@ -12,8 +12,8 @@
"collection.Create update time": "建立/更新時間",
"collection.Training type": "分段模式",
"collection.training_type": "處理模式",
"collection_data_count": "資料量",
"collection_metadata_custom_pdf_parse": "PDF 增強解析",
"collection_data_count": "數據量",
"collection_metadata_custom_pdf_parse": "PDF增強解析",
"collection_metadata_image_parse": "圖片標註",
"collection_not_support_retraining": "此集合類型不支援重新調整參數",
"collection_not_support_sync": "該集合不支援同步",
@@ -22,13 +22,13 @@
"collection_tags": "集合標籤",
"common_dataset": "通用資料集",
"common_dataset_desc": "可透過匯入檔案、網頁連結或手動輸入的方式建立資料集",
"config_sync_schedule": "設定定時同步",
"config_sync_schedule": "配置定時同步",
"confirm_to_rebuild_embedding_tip": "確定要為資料集切換索引嗎?\n切換索引是一個重要的操作需要對您資料集內所有資料重新建立索引可能需要較長時間請確保帳號內剩餘點數充足。\n\n此外您還需要注意修改使用此資料集的應用程式避免與其他索引模型資料集混用。",
"core.dataset.import.Adjust parameters": "調整參數",
"custom_data_process_params": "自訂",
"custom_data_process_params_desc": "自訂資料處理規則",
"custom_split_sign_tip": "允許你根據自定義的分隔符進行分塊。\n通常用於已處理好的資料,使用特定的分隔符來精確分塊。\n可以使用 | 符號表示多個分割符,例如:“。|.”表示中英文句號。\n\n盡量避免使用正則相關特殊符號例如* () [] {} 等。",
"data_amount": "{{dataAmount}} 組資料,{{indexAmount}} 組索引",
"custom_split_sign_tip": "允許你根據自定義的分隔符進行分塊。\n通常用於已處理好的數據,使用特定的分隔符來精確分塊。\n可以使用 | 符號表示多個分割符,例如:“。|.” 表示中英文句號。\n\n盡量避免使用正則相關特殊符號例如: * () [] {} 等。",
"data_amount": "{{dataAmount}} 組數據, {{indexAmount}} 組索引",
"data_error_amount": "{{errorAmount}} 組訓練異常",
"data_index_num": "索引 {{index}}",
"data_process_params": "處理參數",
@@ -37,8 +37,8 @@
"dataset.Completed": "完成",
"dataset.Delete_Chunk": "刪除",
"dataset.Edit_Chunk": "編輯",
"dataset.Error_Message": "報錯資訊",
"dataset.No_Error": "暫無異常資訊",
"dataset.Error_Message": "報錯信息",
"dataset.No_Error": "暫無異常信息",
"dataset.Operation": "操作",
"dataset.ReTrain": "重試",
"dataset.Training Process": "訓練狀態",
@@ -46,13 +46,13 @@
"dataset.Training_Errors": "異常",
"dataset.Training_QA": "{{count}} 組問答對訓練中",
"dataset.Training_Status": "訓練狀態",
"dataset.Training_Waiting": "需等待 {{count}} 組資料",
"dataset.Unsupported operation": "操作不支",
"dataset.Training_Waiting": "需等待 {{count}} 組數據",
"dataset.Unsupported operation": "操作不支",
"dataset.no_collections": "尚無資料集",
"dataset.no_tags": "尚無標籤",
"default_params": "預設",
"default_params_desc": "使用系統預設的參數和規則",
"edit_dataset_config": "編輯知識庫設定",
"default_params_desc": "使用系統默認的參數和規則",
"edit_dataset_config": "編輯知識庫配置",
"enhanced_indexes": "索引增強",
"error.collectionNotFound": "找不到集合",
"external_file": "外部檔案庫",
@@ -62,44 +62,44 @@
"external_read_url_tip": "可以設定您檔案庫的讀取網址,方便對使用者進行讀取權限驗證。目前可使用 {{fileId}} 變數來代表外部檔案識別碼。",
"external_url": "檔案存取網址",
"feishu_dataset": "飛書知識庫",
"feishu_dataset_config": "設定飛書知識庫",
"feishu_dataset_desc": "可透過設定飛書文權限,使用飛書文件建構知識庫,文不會進行二次存",
"feishu_dataset_config": "配置飛書知識庫",
"feishu_dataset_desc": "可通過配置飛書文權限,使用飛書文檔構建知識庫,文不會進行二次存",
"file_list": "文件列表",
"file_model_function_tip": "用於增強索引和問答生成",
"filename": "檔案名稱",
"folder_dataset": "資料夾",
"image_auto_parse": "圖片自動索引",
"image_auto_parse_tips": "呼叫 VLM 自動標註文裡的圖片,並生成額外的檢索索引",
"image_auto_parse_tips": "調用 VLM 自動標註文裡的圖片,並生成額外的檢索索引",
"image_training_queue": "圖片處理排隊",
"immediate_sync": "立即同步",
"import.Auto mode Estimated Price Tips": "需呼叫文字理解模型,將消耗較多 AI 點數:{{price}} 點數 / 1K tokens",
"import.Embedding Estimated Price Tips": "僅使用索引模型,消耗少量 AI 點數:{{price}} 點數 / 1K tokens",
"import_confirm": "確認上傳",
"import_data_preview": "資料預覽",
"import_data_process_setting": "資料處理方式設",
"import_file_parse_setting": "文件解析設",
"import_data_preview": "數據預覽",
"import_data_process_setting": "數據處理方式設",
"import_file_parse_setting": "文件解析設",
"import_model_config": "模型選擇",
"import_param_setting": "參數設",
"import_param_setting": "參數設",
"import_select_file": "選擇文件",
"import_select_link": "輸入連結",
"import_select_link": "輸入鏈接",
"index_size": "索引大小",
"index_size_tips": "向量化時內容的長度,系統會自動按該大小對分塊進行進一步的分割。",
"is_open_schedule": "啟用定時同步",
"keep_image": "保留圖片",
"move.hint": "移動後,所選資料集/資料夾將繼承新資料夾的權限設定,原先的權限設定將失效。",
"open_auto_sync": "開啟定時同步後,系統將每天不定時嘗試同步集合,集合同步期間,會出現無法搜尋到該集合資料現象。",
"params_config": "設定",
"params_setting": "參數設",
"pdf_enhance_parse": "PDF 增強解析",
"params_config": "配置",
"params_setting": "參數設",
"pdf_enhance_parse": "PDF增強解析",
"pdf_enhance_parse_price": "{{price}}積分/頁",
"pdf_enhance_parse_tips": "呼叫 PDF 識別模型進行解析,可以將其轉換成 Markdown 並保留文中的圖片,同時也可以對掃描件進行識別,識別時間較長。",
"pdf_enhance_parse_tips": "調用 PDF 識別模型進行解析,可以將其轉換成 Markdown 並保留文中的圖片,同時也可以對掃描件進行識別,識別時間較長。",
"permission.des.manage": "可管理整個資料集的資料和資訊",
"permission.des.read": "可檢視資料集內容",
"permission.des.write": "可新增和變更資料集內容",
"preview_chunk": "分塊預覽",
"preview_chunk_empty": "文件內容為空",
"preview_chunk_empty": "無法讀取該文件內容",
"preview_chunk_intro": "共 {{total}} 個分塊,最多展示 10 個",
"preview_chunk_not_selected": "點左側文件後進行預覽",
"preview_chunk_not_selected": "點左側文件後進行預覽",
"process.Auto_Index": "自動索引生成",
"process.Get QA": "問答對提取",
"process.Image_Index": "圖片索引生成",
@@ -119,13 +119,12 @@
"split_sign_break2": "2 個換行符",
"split_sign_custom": "自定義",
"split_sign_exclamatiob": "驚嘆號",
"split_sign_null": "不設",
"split_sign_null": "不設",
"split_sign_period": "句號",
"split_sign_question": "問號",
"split_sign_semicolon": "分號",
"start_sync_website_tip": "確認開始同步資料?\n將會刪除舊資料後重新取,請確認!",
"status_error": "執行異常",
"sync_collection_failed": "同步集合錯誤,請檢查是否能正常存取來原始檔",
"start_sync_website_tip": "確認開始同步資料?\n將會刪除舊資料後重新取,請確認!",
"sync_collection_failed": "同步集合錯誤,請檢查是否能正常存取來源文件",
"sync_schedule": "定時同步",
"sync_schedule_tip": "只會同步已存在的集合。\n包括連結集合以及 API 知識庫裡所有集合。\n系統會每天進行輪詢更新無法確定特定的更新時間。",
"tag.Add New": "新增",
@@ -144,12 +143,12 @@
"training.Normal": "正常",
"training_mode": "分段模式",
"training_ready": "{{count}} 組",
"vector_model_max_tokens_tip": "每個分塊資料,最大長度為 3000 tokens",
"vector_model_max_tokens_tip": "每個分塊數據,最大長度為 3000 tokens",
"vllm_model": "圖片理解模型",
"website_dataset": "網站同步",
"website_dataset_desc": "網站同步功能讓您可以直接使用網頁連結建立資料集",
"website_info": "網站資訊",
"yuque_dataset": "語雀知識庫",
"yuque_dataset_config": "設定語雀知識庫",
"yuque_dataset_desc": "可透過設定語雀文權限,使用語雀文件建構知識庫,文不會進行二次存"
"yuque_dataset_config": "配置語雀知識庫",
"yuque_dataset_desc": "可通過配置語雀文權限,使用語雀文檔構建知識庫,文不會進行二次存"
}

View File

@@ -8,7 +8,7 @@
"login_success": "登入成功",
"no_remind": "不再提醒",
"password_condition": "密碼最多 60 個字元",
"password_tip": "密碼至少 6 位,且至少包含兩種組合:數字、字母或特殊字",
"password_tip": "密碼至少 6 位,且至少包含兩種組合:數字、字母或特殊字",
"policy_tip": "使用即代表您同意我們的",
"privacy": "隱私權政策",
"privacy_policy": "隱私權政策",

View File

@@ -55,7 +55,7 @@
"permission.only_collaborators": "僅協作者可存取",
"permission.team_read": "團隊可存取",
"permission.team_write": "團隊可編輯",
"permission_add_tip": "新增後,您可為其勾選權限。",
"permission_add_tip": "添加後,您可為其勾選權限。",
"permission_des.manage": "可建立資源、邀請及刪除成員",
"permission_des.read": "成員僅能閱讀相關資源,無法建立新資源",
"permission_des.write": "除了可讀取資源外,還可以建立新的資源",
@@ -75,7 +75,7 @@
"synchronization.title": "填寫標籤同步連結,點選同步按鈕即可同步",
"team.Add manager": "新增管理員",
"team.Confirm Invite": "確認邀請",
"team.Create Team": "建新團隊",
"team.Create Team": "建新團隊",
"team.Invite Member Failed Tip": "邀請成員出現異常",
"team.Invite Member Result Tip": "邀請結果提示",
"team.Invite Member Success Tip": "邀請成員完成\n\n成功{{success}} 人\n\n使用者名稱無效{{inValid}}\n\n已在團隊中{{inTeam}}",
@@ -97,9 +97,10 @@
"team.group.group": "群組",
"team.group.keep_admin": "保留管理員權限",
"team.group.manage_member": "管理成員",
"team.group.manage_tip": "可以管理成員、建群組、管理所有群組、為群組和成員分配權限",
"team.group.manage_tip": "可以管理成員、建群組、管理所有群組、為群組和成員分配權限",
"team.group.members": "成員",
"team.group.name": "群組名稱",
"team.group.permission.manage": "管理員",
"team.group.permission.write": "工作臺/知識庫建立",
"team.group.permission_tip": "單獨設定權限的成員,將依照個人權限設定,不再受群組權限影響。\n若成員屬於多個權限群組該成員的權限將會合併。",
"team.group.role.admin": "管理員",
@@ -111,6 +112,5 @@
"team.manage_collaborators": "管理協作者",
"team.no_collaborators": "目前沒有協作者",
"team.org.org": "組織",
"team.write_role_member": "可寫入權限",
"team.collaborator.added": "已新增"
"team.write_role_member": "可寫入權限"
}

View File

@@ -14,13 +14,13 @@
"application_call": "應用程式呼叫",
"assigned_reply": "指定回覆",
"auth_tmb_id": "使用者鑑權",
"auth_tmb_id_tip": "開啟後,對外發布應用程式時,也會根據使用者是否有該知識庫權限進行知識庫過濾。\n\n若未開啟則直接按設定的知識庫進行檢索,不進行權限過濾。",
"auth_tmb_id_tip": "開啟後,對外發布應用程式時,也會根據使用者是否有該知識庫權限進行知識庫過濾。\n\n若未開啟則直接按配置的知識庫進行檢索,不進行權限過濾。",
"can_not_loop": "這個節點不能迴圈。",
"choose_another_application_to_call": "選擇另一個應用程式來呼叫",
"classification_result": "分類結果",
"code.Reset template": "重設範本",
"code.Reset template confirm": "確定要重設程式碼範本嗎?這將會把所有輸入和輸出重設為範本值。請儲存您目前的程式碼。",
"code.Switch language confirm": "切換語言將重代碼,是否繼續?",
"code.Switch language confirm": "切換語言將重代碼,是否繼續?",
"code_execution": "程式碼執行",
"collection_metadata_filter": "資料集詮釋資料篩選器",
"complete_extraction_result": "完整擷取結果",
@@ -52,7 +52,7 @@
"execution_error": "執行錯誤",
"extraction_requirements_description": "擷取需求描述",
"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": "回饋文字",
"field_description": "欄位描述",
"field_description_placeholder": "描述這個輸入欄位的功能,如果是工具呼叫參數,這個描述會影響模型產生的品質",
@@ -77,7 +77,6 @@
"ifelse.Input value": "輸入值",
"ifelse.Select value": "選擇值",
"input_description": "欄位描述",
"input_type_multiple_select": "多選框",
"input_variable_list": "輸入 / 叫出變數清單",
"intro_assigned_reply": "這個模組可以直接回覆指定的內容。常用於引導、提示。非字串內容傳入時,會轉換成字串輸出。",
"intro_custom_feedback": "當這個模組被觸發時,會在目前的對話紀錄中新增一條回饋。可以用於自動記錄對話效果等等。",
@@ -85,7 +84,7 @@
"intro_http_request": "可以傳送 HTTP 請求,執行更複雜的操作(網路搜尋、資料庫查詢等等)",
"intro_knowledge_base_search_merge": "可以合併多個知識庫搜尋結果並輸出。使用 RRF 合併方法進行最終排序輸出。",
"intro_laf_function_call": "可以呼叫 Laf 帳號下的雲端函式。",
"intro_loop": "輸入一個陣列,遍歷陣列並將每個陣列元素作為輸入元素,執行工作流程。",
"intro_loop": "輸入一個數組,遍歷數組並將每個數組元素作為輸入元素,執行工作流程。",
"intro_plugin_input": "可以設定外掛程式需要的輸入,並利用這些輸入來執行外掛程式",
"intro_question_classification": "根據使用者的歷史紀錄和目前問題判斷這次提問的類型。可以新增多個問題類型,以下是一個範例:\n類型 1打招呼\n類型 2關於產品「使用方式」的問題\n類型 3關於產品「購買」的問題\n類型 4其他問題",
"intro_question_optimization": "使用問題最佳化功能,可以提升知識庫連續對話時的搜尋精準度。使用這個功能後,會先利用 AI 根據脈絡建構一個或多個新的檢索詞彙,這些詞彙更有利於知識庫搜尋。這個模組已內建於知識庫搜尋模組中,如果您只進行一次知識庫搜尋,可以直接使用知識庫內建的自動完成功能。",
@@ -135,7 +134,7 @@
"question_classification": "問題分類",
"question_optimization": "問題最佳化",
"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_prompt_tip": "可以使用 {{quote}} 來插入引用內容範本,使用 {{question}} 來插入問題Role=user。\n以下是預設值\n{{default}}",
"quote_role_system_tip": "請注意從「引用範本提示詞」中移除 {{question}} 變數",
@@ -153,10 +152,9 @@
"response.read files": "解析的檔案",
"select_an_application": "選擇一個應用程式",
"select_another_application_to_call": "可以選擇另一個應用程式來呼叫",
"select_default_option": "選擇默認值",
"special_array_format": "特殊陣列格式,搜尋結果為空時,回傳空陣列。",
"start_with": "開頭為",
"support_code_language": "支import 列表pandasnumpy",
"support_code_language": "支import列表pandasnumpy",
"target_fields_description": "由「描述」和「鍵值」組成一個目標欄位,可以擷取多個目標欄位",
"template.ai_chat": "AI 對話",
"template.ai_chat_intro": "AI 大型語言模型對話",

542
pnpm-lock.yaml generated
View File

@@ -4,9 +4,6 @@ settings:
autoInstallPeers: true
excludeLinksFromLockfile: false
overrides:
mdast-util-gfm-autolink-literal: 2.0.0
importers:
.:
@@ -15,8 +12,8 @@ importers:
specifier: ^2.4.1
version: 2.5.8(encoding@0.1.13)(react@18.3.1)
'@vitest/coverage-v8':
specifier: ^3.0.9
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))
specifier: ^3.0.2
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))
husky:
specifier: ^8.0.3
version: 8.0.3
@@ -26,9 +23,6 @@ importers:
lint-staged:
specifier: ^13.3.0
version: 13.3.0
mongodb-memory-server:
specifier: ^10.1.4
version: 10.1.4(socks@2.8.4)
next-i18next:
specifier: 15.4.2
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)
@@ -39,8 +33,11 @@ importers:
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)
vitest:
specifier: ^3.0.9
version: 3.1.1(@types/debug@4.1.12)(@types/node@20.17.24)(sass@1.85.1)(terser@5.39.0)
specifier: ^3.0.2
version: 3.0.8(@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:
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)
@@ -254,8 +251,8 @@ importers:
specifier: 5.4.1
version: 5.4.1
pdfjs-dist:
specifier: 4.10.38
version: 4.10.38
specifier: 4.4.168
version: 4.4.168(encoding@0.1.13)
pg:
specifier: ^8.10.0
version: 8.14.0
@@ -2303,6 +2300,10 @@ packages:
resolution: {integrity: sha512-9I2Zn6+NJLfaGoz9jN3lpwDgAYvfGeNYdbAIjJOqzs4Tpc+VU3Jqq4IofSUBKajiDS8k9fZIg18/z13mpk1bsA==}
engines: {node: '>=8'}
'@mapbox/node-pre-gyp@1.0.11':
resolution: {integrity: sha512-Yhlar6v9WQgUp/He7BdgzOz8lqMQ8sU+jkCq7Wx8Myc5YFJLbEe7lgui/V7G1qB1DJykHSGwreceSaD60Y0PUQ==}
hasBin: true
'@microsoft/tsdoc@0.15.1':
resolution: {integrity: sha512-4aErSrCR/On/e5G2hDP0wjooqDdauzEbIq8hIkIe5pXV0rtWJZvdCEKL0ykZxex+IxIwBp0eGeV48hQN07dXtw==}
@@ -2352,70 +2353,6 @@ packages:
cpu: [x64]
os: [win32]
'@napi-rs/canvas-android-arm64@0.1.69':
resolution: {integrity: sha512-4icWTByY8zPvM9SelfQKf3I6kwXw0aI5drBOVrwfER5kjwXJd78FPSDSZkxDHjvIo9Q86ljl18Yr963ehA4sHQ==}
engines: {node: '>= 10'}
cpu: [arm64]
os: [android]
'@napi-rs/canvas-darwin-arm64@0.1.69':
resolution: {integrity: sha512-HOanhhYlHdukA+unjelT4Dg3ta7e820x87/AG2dKUMsUzH19jaeZs9bcYjzEy2vYi/dFWKz7cSv2yaIOudB8Yg==}
engines: {node: '>= 10'}
cpu: [arm64]
os: [darwin]
'@napi-rs/canvas-darwin-x64@0.1.69':
resolution: {integrity: sha512-SIp7WfhxAPnSVK9bkFfJp+84rbATCIq9jMUzDwpCLhQ+v+OqtXe4pggX1oeV+62/HK6BT1t18qRmJfyqwJ9f3g==}
engines: {node: '>= 10'}
cpu: [x64]
os: [darwin]
'@napi-rs/canvas-linux-arm-gnueabihf@0.1.69':
resolution: {integrity: sha512-Ls+KujCp6TGpkuMVFvrlx+CxtL+casdkrprFjqIuOAnB30Mct6bCEr+I83Tu29s3nNq4EzIGjdmA3fFAZG/Dtw==}
engines: {node: '>= 10'}
cpu: [arm]
os: [linux]
'@napi-rs/canvas-linux-arm64-gnu@0.1.69':
resolution: {integrity: sha512-m8VcGmeSBNRbHZBd1srvdM1aq/ScS2y8KqGqmCCEgJlytYK4jdULzAo2K/BPKE1v3xvn8oUPZDLI/NBJbJkEoA==}
engines: {node: '>= 10'}
cpu: [arm64]
os: [linux]
'@napi-rs/canvas-linux-arm64-musl@0.1.69':
resolution: {integrity: sha512-a3xjNRIeK2m2ZORGv2moBvv3vbkaFZG1QKMeiEv/BKij+rkztuEhTJGMar+buICFgS0fLgphXXsKNkUSJb7eRQ==}
engines: {node: '>= 10'}
cpu: [arm64]
os: [linux]
'@napi-rs/canvas-linux-riscv64-gnu@0.1.69':
resolution: {integrity: sha512-pClUoJF5wdC9AvD0mc15G9JffL1Q85nuH1rLSQPRkGmGmQOtRjw5E9xNbanz7oFUiPbjH7xcAXUjVAcf7tdgPQ==}
engines: {node: '>= 10'}
cpu: [riscv64]
os: [linux]
'@napi-rs/canvas-linux-x64-gnu@0.1.69':
resolution: {integrity: sha512-96X3bFAmzemfw84Ts6Jg/omL86uuynvK06MWGR/mp3JYNumY9RXofA14eF/kJIYelbYFWXcwpbcBR71lJ6G/YQ==}
engines: {node: '>= 10'}
cpu: [x64]
os: [linux]
'@napi-rs/canvas-linux-x64-musl@0.1.69':
resolution: {integrity: sha512-2QTsEFO72Kwkj53W9hc5y1FAUvdGx0V+pjJB+9oQF6Ys9+y989GyPIl5wZDzeh8nIJW6koZZ1eFa8pD+pA5BFQ==}
engines: {node: '>= 10'}
cpu: [x64]
os: [linux]
'@napi-rs/canvas-win32-x64-msvc@0.1.69':
resolution: {integrity: sha512-Q4YA8kVnKarApBVLu7F8icGlIfSll5Glswo5hY6gPS4Is2dCI8+ig9OeDM8RlwYevUIxKq8lZBypN8Q1iLAQ7w==}
engines: {node: '>= 10'}
cpu: [x64]
os: [win32]
'@napi-rs/canvas@0.1.69':
resolution: {integrity: sha512-ydvNeJMRm+l3T14yCoUKqjYQiEdXDq1isznI93LEBGYssXKfSaLNLHOkeM4z9Fnw9Pkt2EKOCAtW9cS4b00Zcg==}
engines: {node: '>= 10'}
'@napi-rs/wasm-runtime@0.2.7':
resolution: {integrity: sha512-5yximcFK5FNompXfJFoWanu5l8v1hNGqNHh9du1xETp9HWk/B/PzvchX55WYOPaIeNglG8++68AAiauBAtbnzw==}
@@ -3563,11 +3500,11 @@ packages:
'@ungap/structured-clone@1.3.0':
resolution: {integrity: sha512-WmoN8qaIAo7WTYWbAZuG8PYEhn5fkz7dZrqTBZ7dtt//lL2Gwms1IcnQ5yHqjDfX8Ft5j4YzDM23f87zBfDe9g==}
'@vitest/coverage-v8@3.1.1':
resolution: {integrity: sha512-MgV6D2dhpD6Hp/uroUoAIvFqA8AuvXEFBC2eepG3WFc1pxTfdk1LEqqkWoWhjz+rytoqrnUUCdf6Lzco3iHkLQ==}
'@vitest/coverage-v8@3.0.8':
resolution: {integrity: sha512-y7SAKsQirsEJ2F8bulBck4DoluhI2EEgTimHd6EEUgJBGKy9tC25cpywh1MH4FvDGoG2Unt7+asVd1kj4qOSAw==}
peerDependencies:
'@vitest/browser': 3.1.1
vitest: 3.1.1
'@vitest/browser': 3.0.8
vitest: 3.0.8
peerDependenciesMeta:
'@vitest/browser':
optional: true
@@ -3578,9 +3515,6 @@ packages:
'@vitest/expect@3.0.8':
resolution: {integrity: sha512-Xu6TTIavTvSSS6LZaA3EebWFr6tsoXPetOWNMOlc7LO88QVVBwq2oQWBoDiLCN6YTvNYsGSjqOO8CAdjom5DCQ==}
'@vitest/expect@3.1.1':
resolution: {integrity: sha512-q/zjrW9lgynctNbwvFtQkGK9+vvHA5UzVi2V8APrp1C6fG6/MuYYkmlx4FubuqLycCeSdHD5aadWfua/Vr0EUA==}
'@vitest/mocker@3.0.8':
resolution: {integrity: sha512-n3LjS7fcW1BCoF+zWZxG7/5XvuYH+lsFg+BDwwAz0arIwHQJFUEsKBQ0BLU49fCxuM/2HSeBPHQD8WjgrxMfow==}
peerDependencies:
@@ -3592,59 +3526,33 @@ packages:
vite:
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':
resolution: {integrity: sha512-BNqwbEyitFhzYMYHUVbIvepOyeQOSFA/NeJMIP9enMntkkxLgOcgABH6fjyXG85ipTgvero6noreavGIqfJcIg==}
'@vitest/pretty-format@3.1.1':
resolution: {integrity: sha512-dg0CIzNx+hMMYfNmSqJlLSXEmnNhMswcn3sXO7Tpldr0LiGmg3eXdLLhwkv2ZqgHb/d5xg5F7ezNFRA1fA13yA==}
'@vitest/runner@1.6.1':
resolution: {integrity: sha512-3nSnYXkVkf3mXFfE7vVyPmi3Sazhb/2cfZGGs0JRzFsPFvAMBEcrweV1V1GsrstdXeKCTXlJbvnQwGWgEIHmOA==}
'@vitest/runner@3.0.8':
resolution: {integrity: sha512-c7UUw6gEcOzI8fih+uaAXS5DwjlBaCJUo7KJ4VvJcjL95+DSR1kova2hFuRt3w41KZEFcOEiq098KkyrjXeM5w==}
'@vitest/runner@3.1.1':
resolution: {integrity: sha512-X/d46qzJuEDO8ueyjtKfxffiXraPRfmYasoC4i5+mlLEJ10UvPb0XH5M9C3gWuxd7BAQhpK42cJgJtq53YnWVA==}
'@vitest/snapshot@1.6.1':
resolution: {integrity: sha512-WvidQuWAzU2p95u8GAKlRMqMyN1yOJkGHnx3M1PL9Raf7AQ1kwLKg04ADlCa3+OXUZE7BceOhVZiuWAbzCKcUQ==}
'@vitest/snapshot@3.0.8':
resolution: {integrity: sha512-x8IlMGSEMugakInj44nUrLSILh/zy1f2/BgH0UeHpNyOocG18M9CWVIFBaXPt8TrqVZWmcPjwfG/ht5tnpba8A==}
'@vitest/snapshot@3.1.1':
resolution: {integrity: sha512-bByMwaVWe/+1WDf9exFxWWgAixelSdiwo2p33tpqIlM14vW7PRV5ppayVXtfycqze4Qhtwag5sVhX400MLBOOw==}
'@vitest/spy@1.6.1':
resolution: {integrity: sha512-MGcMmpGkZebsMZhbQKkAf9CX5zGvjkBTqf8Zx3ApYWXr3wG+QvEu2eXWfnIIWYSJExIp4V9FCKDEeygzkYrXMw==}
'@vitest/spy@3.0.8':
resolution: {integrity: sha512-MR+PzJa+22vFKYb934CejhR4BeRpMSoxkvNoDit68GQxRLSf11aT6CTj3XaqUU9rxgWJFnqicN/wxw6yBRkI1Q==}
'@vitest/spy@3.1.1':
resolution: {integrity: sha512-+EmrUOOXbKzLkTDwlsc/xrwOlPDXyVk3Z6P6K4oiCndxz7YLpp/0R0UsWVOKT0IXWjjBJuSMk6D27qipaupcvQ==}
'@vitest/utils@1.6.1':
resolution: {integrity: sha512-jOrrUvXM4Av9ZWiG1EajNto0u96kWAhJ1LmPmJhXXQx/32MecEKd10pOLYgS2BQx1TgkGhloPU1ArDW2vvaY6g==}
'@vitest/utils@3.0.8':
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':
resolution: {integrity: sha512-oOdAkwqUfW1WqpwSYJce06wvt6HljgY3fGeM9NcVA1HaYOij3mZG9Rkysn0OHuyUAGMbEbARIpsG+LPVlBJ5/Q==}
@@ -3741,6 +3649,9 @@ packages:
'@zilliz/milvus2-sdk-node@2.4.2':
resolution: {integrity: sha512-fkPu7XXzfUvHoCnSPVOjqQpWuSnnn9x2NMmmCcIOyRzMeXIsrz4Mf/+M7LUzmT8J9F0Khx65B0rJgCu27YzWQw==}
abbrev@1.1.1:
resolution: {integrity: sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==}
abbrev@2.0.0:
resolution: {integrity: sha512-6/mh1E2u2YgEsCHdY0Yx5oW+61gZU+1vXaoiHHrpKeuRNNgFvS+/jrwHiQhB5apAf5oB7UB7E19ol2R2LKH8hQ==}
engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0}
@@ -3770,6 +3681,10 @@ packages:
engines: {node: '>=0.4.0'}
hasBin: true
agent-base@6.0.2:
resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==}
engines: {node: '>= 6.0.0'}
agent-base@7.1.3:
resolution: {integrity: sha512-jRR5wdylq8CkOe6hei19GGZnxM6rBGwFl3Bg0YItGDimvjGtAvdZk4Pu6Cl4u4Igsws4a1fd1Vq3ezrhn4KmFw==}
engines: {node: '>= 14'}
@@ -3877,6 +3792,14 @@ packages:
append-field@1.0.0:
resolution: {integrity: sha512-klpgFSWLW1ZEs8svjfb7g4qWY0YS5imI82dTg+QahUvJ8YqAY0P10Uk8tTyh9ZGuYEZEMaeJYCF5BFuX552hsw==}
aproba@2.0.0:
resolution: {integrity: sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==}
are-we-there-yet@2.0.0:
resolution: {integrity: sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw==}
engines: {node: '>=10'}
deprecated: This package is no longer supported.
arg@4.1.3:
resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==}
@@ -4202,6 +4125,10 @@ packages:
caniuse-lite@1.0.30001704:
resolution: {integrity: sha512-+L2IgBbV6gXB4ETf0keSvLr7JUrRVbIaB/lrQ1+z8mRcQiisG5k+lG6O4n6Y5q6f5EuNfaYXKgymucphlEXQew==}
canvas@2.11.2:
resolution: {integrity: sha512-ItanGBMrmRV7Py2Z+Xhs7cT+FNt5K0vPL4p9EZ/UX/Mu7hFbkxSjKF2KVtPwX7UYWp7dRKnrTvReflgrItJbdw==}
engines: {node: '>=6'}
ccount@2.0.1:
resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==}
@@ -4393,6 +4320,10 @@ packages:
color-string@1.9.1:
resolution: {integrity: sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==}
color-support@1.1.3:
resolution: {integrity: sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==}
hasBin: true
color2k@2.0.3:
resolution: {integrity: sha512-zW190nQTIoXcGCaU08DvVNFTmQhUpnJfVuAKfWqUQkflXKpaDdpaYoM0iluLS9lgJNHyBF58KKA2FBEwkD7wog==}
@@ -4468,6 +4399,9 @@ packages:
consola@2.15.3:
resolution: {integrity: sha512-9vAdYbHj6x2fLKC4+oPH0kFzY/orMZyG2Aj+kNylHxKGJ/Ed4dpNyAQYwJOdqO4zdM7XpVHmyejQDcQHrnuXbw==}
console-control-strings@1.1.0:
resolution: {integrity: sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==}
content-disposition@0.5.4:
resolution: {integrity: sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==}
engines: {node: '>= 0.6'}
@@ -4796,6 +4730,10 @@ packages:
decode-named-character-reference@1.1.0:
resolution: {integrity: sha512-Wy+JTSbFThEOXQIR2L6mxJvEs+veIzpmqD7ynWxMXGpnk3smkHQOp6forLdHsKpAMW9iJpaBBIxz285t1n1C3w==}
decompress-response@4.2.1:
resolution: {integrity: sha512-jOSne2qbyE+/r8G1VU+G/82LBs2Fs4LAsTiLSHOCOMZQl2OKZ6i8i4IyHemTe+/yIXOtTcRQMzPcgyhoFlqPkw==}
engines: {node: '>=8'}
decompress-response@6.0.0:
resolution: {integrity: sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==}
engines: {node: '>=10'}
@@ -4881,6 +4819,9 @@ packages:
resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==}
engines: {node: '>=0.4.0'}
delegates@1.0.0:
resolution: {integrity: sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==}
denque@2.1.0:
resolution: {integrity: sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw==}
engines: {node: '>=0.10'}
@@ -5590,6 +5531,11 @@ packages:
functions-have-names@1.2.3:
resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==}
gauge@3.0.2:
resolution: {integrity: sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q==}
engines: {node: '>=10'}
deprecated: This package is no longer supported.
generate-function@2.3.1:
resolution: {integrity: sha512-eeB5GfMNeevm/GRYq20ShmsaGcmI81kIX2K9XQx5miC8KdHaC6Jm0qQ8ZNeGOi7wYB8OsdxKs+Y2oVuTFuVwKQ==}
@@ -5742,6 +5688,9 @@ packages:
resolution: {integrity: sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==}
engines: {node: '>= 0.4'}
has-unicode@2.0.1:
resolution: {integrity: sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==}
has-yarn@3.0.0:
resolution: {integrity: sha512-IrsVwUHhEULx3R8f/aA8AHuEzAorplsab/v8HBzEiIukwq5i/EC+xmOW+HfP1OaDP+2JkgT1yILHN2O3UFIbcA==}
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
@@ -5829,6 +5778,10 @@ packages:
resolution: {integrity: sha512-V5nVw1PAOgfI3Lmeaj2Exmeg7fenjhRUgz1lPSezy1CuhPYbgQtbQj4jZfEAEMlaL+vupsvhjqCyjzob0yxsmQ==}
engines: {node: '>=10.19.0'}
https-proxy-agent@5.0.1:
resolution: {integrity: sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==}
engines: {node: '>= 6'}
https-proxy-agent@7.0.6:
resolution: {integrity: sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==}
engines: {node: '>= 14'}
@@ -6591,8 +6544,8 @@ packages:
lexical@0.14.5:
resolution: {integrity: sha512-ouV7Gyr9+3WT3WTrCgRAD3iZnlJWfs2/kBl2x3J2Q3X9uCWJn/zn21fQ8G1EUHlu0dvXPBmdk9hXb/FjTClt6Q==}
lib0@0.2.102:
resolution: {integrity: sha512-g70kydI0I1sZU0ChO8mBbhw0oUW/8U0GHzygpvEIx8k+jgOpqnTSb/E+70toYVqHxBhrERD21TwD5QcZJQ40ZQ==}
lib0@0.2.99:
resolution: {integrity: sha512-vwztYuUf1uf/1zQxfzRfO5yzfNKhTtgOByCruuiQQxWQXnPb8Itaube5ylofcV0oM0aKal9Mv+S1s1Ky0UYP1w==}
engines: {node: '>=16'}
hasBin: true
@@ -6810,8 +6763,8 @@ packages:
mdast-util-from-markdown@2.0.2:
resolution: {integrity: sha512-uZhTV/8NBuw0WHkPTrCqDOl0zVe1BIng5ZtHoDk49ME1qqcjYmmLmOf0gELgcRMxN4w2iuIeVso5/6QymSrgmA==}
mdast-util-gfm-autolink-literal@2.0.0:
resolution: {integrity: sha512-FyzMsduZZHSc3i0Px3PQcBT4WJY/X/RCtEJKuybiC6sjPqLv7h1yqAkmILZtuxMSsUyaLUWNp71+vQH2zqp5cg==}
mdast-util-gfm-autolink-literal@2.0.1:
resolution: {integrity: sha512-5HVP2MKaP6L+G6YaxPNjuL0BPrq9orG3TsrZ9YXbA3vDw/ACI4MEsnoDpn6ZNm7GnZgtAcONJyPhOP8tNJQavQ==}
mdast-util-gfm-footnote@2.1.0:
resolution: {integrity: sha512-sqpDWlsHn7Ac9GNZQMeUzPQSMzR6Wv0WKRNvQRg0KqHh02fpTz69Qc1QSseNX29bhz1ROIyNyxExfawVKTm1GQ==}
@@ -7081,6 +7034,10 @@ packages:
resolution: {integrity: sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==}
engines: {node: '>=12'}
mimic-response@2.1.0:
resolution: {integrity: sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA==}
engines: {node: '>=8'}
mimic-response@3.1.0:
resolution: {integrity: sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==}
engines: {node: '>=10'}
@@ -7258,6 +7215,9 @@ packages:
resolution: {integrity: sha512-eLoBxg6wE/rZkJPhU/xRX1WTpkFEwDJEN96oxFrTsqBdbT5ec295Q+CoHrL9IT0DipqKhmGcaZmwOt8OON5x1w==}
engines: {node: '>=12.0.0'}
nan@2.22.2:
resolution: {integrity: sha512-DANghxFkS1plDdRsX0X9pm0Z6SJNN6gBdtXfanwoZ8hooC5gosGFSBGRYHUVPz1asKA/kMRqDRdHrluZ61SpBQ==}
nanoid@3.3.9:
resolution: {integrity: sha512-SppoicMGpZvbF1l3z4x7No3OlIjP7QJvC9XR7AhZr1kL133KHnKPztkKDc+Ir4aJ/1VhTySrtKhrsycmrMQfvg==}
engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
@@ -7390,6 +7350,11 @@ packages:
non-layered-tidy-tree-layout@2.0.2:
resolution: {integrity: sha512-gkXMxRzUH+PB0ax9dUN0yYF0S25BqeAYqhgMaLUFmpXLEk7Fcu8f4emJuOAY0V8kjDICxROIKsTAKsV/v355xw==}
nopt@5.0.0:
resolution: {integrity: sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==}
engines: {node: '>=6'}
hasBin: true
nopt@7.2.1:
resolution: {integrity: sha512-taM24ViiimT/XntxbPyJQzCG+p4EKOpgD3mxFwW38mGjVUrfERQOeY4EDHjdnptttfHuHQXFx+lTP08Q+mLa/w==}
engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0}
@@ -7411,6 +7376,10 @@ packages:
resolution: {integrity: sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==}
engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
npmlog@5.0.1:
resolution: {integrity: sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw==}
deprecated: This package is no longer supported.
nprogress@0.2.0:
resolution: {integrity: sha512-I19aIingLgR1fmhftnbWWO3dXc0hSxqHQHQb3H8m+K3TnEn/iSeTZZOyvKXWqQESMwuUVnatlCnZdLBZZt2VSA==}
@@ -7639,6 +7608,10 @@ packages:
resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==}
engines: {node: '>=8'}
path2d@0.2.2:
resolution: {integrity: sha512-+vnG6S4dYcYxZd+CZxzXCNKdELYZSKfohrk98yajCo1PtRoDgCTrrwOvK1GT0UoAdVszagDVllQc0U1vaX4NUQ==}
engines: {node: '>=6'}
pathe@1.1.2:
resolution: {integrity: sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==}
@@ -7652,9 +7625,9 @@ packages:
resolution: {integrity: sha512-vE7JKRyES09KiunauX7nd2Q9/L7lhok4smP9RZTDeD4MVs72Dp2qNFVz39Nz5a0FVEW0BJR6C0DYrq6unoziZA==}
engines: {node: '>= 14.16'}
pdfjs-dist@4.10.38:
resolution: {integrity: sha512-/Y3fcFrXEAsMjJXeL9J8+ZG9U01LbuWaYypvDW2ycW1jL269L3js3DVBjDJ0Up9Np1uqDXsDrRihHANhZOlwdQ==}
engines: {node: '>=20'}
pdfjs-dist@4.4.168:
resolution: {integrity: sha512-MbkAjpwka/dMHaCfQ75RY1FXX3IewBVu6NGZOcxerRFlaBiIkZmUoR0jotX5VUzYZEXAGzSFtknWs5xRKliXPA==}
engines: {node: '>=18'}
peek-readable@5.4.2:
resolution: {integrity: sha512-peBp3qZyuS6cNIJ2akRNG1uo1WJ1d0wTxg/fxMdZ0BqCVhx242bSFHM9eNqflfJVS9SsgkzgT/1UgnsurBOTMg==}
@@ -8491,6 +8464,9 @@ packages:
simple-concat@1.0.1:
resolution: {integrity: sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==}
simple-get@3.1.1:
resolution: {integrity: sha512-CQ5LTKGfCpvE1K0n2us+kuMPbk/q0EKl82s4aheV9oXjFEz6W/Y7oQFVJuU6QG77hRT4Ghb5RURteF5vnWjupA==}
simple-get@4.0.1:
resolution: {integrity: sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==}
@@ -9357,11 +9333,6 @@ packages:
engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0}
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:
resolution: {integrity: sha512-EK5cY7Q1D8JNhSaPKVK4pwBFvaTmZxEnoKXLG/U9gmdDcihQGNzFlgIvaxezFR4glP1LsuiedwMBqCXH3wZccA==}
engines: {node: ^18.0.0 || >=20.0.0}
@@ -9433,6 +9404,9 @@ packages:
yaml:
optional: true
vitest-mongodb@1.0.1:
resolution: {integrity: sha512-a9Mc2F35h8qxI1uOgsrCUH28TglClAd8gdXkn7CBqmC6bLr6D2Ibyxp0Xz6/AU0ukAOfuf/6oqUS+ZN0VlxVyQ==}
vitest@1.6.1:
resolution: {integrity: sha512-Ljb1cnSJSivGN0LqXd/zmDbWEM0RNNg2t1QW/XUhYl/qPqyu7CsqeWtqQXHVaJsecLPuDoak2oJcZN2QoRIOag==}
engines: {node: ^18.0.0 || >=20.0.0}
@@ -9486,34 +9460,6 @@ packages:
jsdom:
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:
resolution: {integrity: sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w==}
engines: {node: '>=0.10.0'}
@@ -9612,6 +9558,9 @@ packages:
engines: {node: '>=8'}
hasBin: true
wide-align@1.1.5:
resolution: {integrity: sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==}
widest-line@4.0.1:
resolution: {integrity: sha512-o0cyEG0e8GPzT4iGHphIOh0cJOV8fivsXxddQasHPHfoZf1ZexrfeA21w2NaEN1RHE+fXlfISmOE8R9N3u3Qig==}
engines: {node: '>=12'}
@@ -11661,6 +11610,22 @@ snapshots:
'@lukeed/ms@2.0.2': {}
'@mapbox/node-pre-gyp@1.0.11(encoding@0.1.13)':
dependencies:
detect-libc: 2.0.3
https-proxy-agent: 5.0.1
make-dir: 3.1.0
node-fetch: 2.7.0(encoding@0.1.13)
nopt: 5.0.0
npmlog: 5.0.1
rimraf: 3.0.2
semver: 7.7.1
tar: 6.2.1
transitivePeerDependencies:
- encoding
- supports-color
optional: true
'@microsoft/tsdoc@0.15.1': {}
'@mixmark-io/domino@2.2.0': {}
@@ -11698,50 +11663,6 @@ snapshots:
'@msgpackr-extract/msgpackr-extract-win32-x64@3.0.3':
optional: true
'@napi-rs/canvas-android-arm64@0.1.69':
optional: true
'@napi-rs/canvas-darwin-arm64@0.1.69':
optional: true
'@napi-rs/canvas-darwin-x64@0.1.69':
optional: true
'@napi-rs/canvas-linux-arm-gnueabihf@0.1.69':
optional: true
'@napi-rs/canvas-linux-arm64-gnu@0.1.69':
optional: true
'@napi-rs/canvas-linux-arm64-musl@0.1.69':
optional: true
'@napi-rs/canvas-linux-riscv64-gnu@0.1.69':
optional: true
'@napi-rs/canvas-linux-x64-gnu@0.1.69':
optional: true
'@napi-rs/canvas-linux-x64-musl@0.1.69':
optional: true
'@napi-rs/canvas-win32-x64-msvc@0.1.69':
optional: true
'@napi-rs/canvas@0.1.69':
optionalDependencies:
'@napi-rs/canvas-android-arm64': 0.1.69
'@napi-rs/canvas-darwin-arm64': 0.1.69
'@napi-rs/canvas-darwin-x64': 0.1.69
'@napi-rs/canvas-linux-arm-gnueabihf': 0.1.69
'@napi-rs/canvas-linux-arm64-gnu': 0.1.69
'@napi-rs/canvas-linux-arm64-musl': 0.1.69
'@napi-rs/canvas-linux-riscv64-gnu': 0.1.69
'@napi-rs/canvas-linux-x64-gnu': 0.1.69
'@napi-rs/canvas-linux-x64-musl': 0.1.69
'@napi-rs/canvas-win32-x64-msvc': 0.1.69
optional: true
'@napi-rs/wasm-runtime@0.2.7':
dependencies:
'@emnapi/core': 1.3.1
@@ -12903,7 +12824,7 @@ snapshots:
'@ungap/structured-clone@1.3.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))':
'@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))':
dependencies:
'@ampproject/remapping': 2.3.0
'@bcoe/v8-coverage': 1.0.2
@@ -12917,7 +12838,7 @@ snapshots:
std-env: 3.8.1
test-exclude: 7.0.1
tinyrainbow: 2.0.0
vitest: 3.1.1(@types/debug@4.1.12)(@types/node@20.17.24)(sass@1.85.1)(terser@5.39.0)
vitest: 3.0.8(@types/debug@4.1.12)(@types/node@20.17.24)(sass@1.85.1)(terser@5.39.0)
transitivePeerDependencies:
- supports-color
@@ -12934,13 +12855,6 @@ snapshots:
chai: 5.2.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))':
dependencies:
'@vitest/spy': 3.0.8
@@ -12949,22 +12863,10 @@ snapshots:
optionalDependencies:
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':
dependencies:
tinyrainbow: 2.0.0
'@vitest/pretty-format@3.1.1':
dependencies:
tinyrainbow: 2.0.0
'@vitest/runner@1.6.1':
dependencies:
'@vitest/utils': 1.6.1
@@ -12976,11 +12878,6 @@ snapshots:
'@vitest/utils': 3.0.8
pathe: 2.0.3
'@vitest/runner@3.1.1':
dependencies:
'@vitest/utils': 3.1.1
pathe: 2.0.3
'@vitest/snapshot@1.6.1':
dependencies:
magic-string: 0.30.17
@@ -12993,12 +12890,6 @@ snapshots:
magic-string: 0.30.17
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':
dependencies:
tinyspy: 2.2.1
@@ -13007,10 +12898,6 @@ snapshots:
dependencies:
tinyspy: 3.0.2
'@vitest/spy@3.1.1':
dependencies:
tinyspy: 3.0.2
'@vitest/utils@1.6.1':
dependencies:
diff-sequences: 29.6.3
@@ -13024,12 +12911,6 @@ snapshots:
loupe: 3.1.3
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':
dependencies:
'@babel/parser': 7.26.10
@@ -13185,6 +13066,9 @@ snapshots:
protobufjs: 7.4.0
winston: 3.17.0
abbrev@1.1.1:
optional: true
abbrev@2.0.0: {}
abort-controller@3.0.0:
@@ -13208,6 +13092,13 @@ snapshots:
acorn@8.14.1: {}
agent-base@6.0.2:
dependencies:
debug: 4.4.0
transitivePeerDependencies:
- supports-color
optional: true
agent-base@7.1.3: {}
agentkeepalive@4.6.0:
@@ -13315,6 +13206,15 @@ snapshots:
append-field@1.0.0: {}
aproba@2.0.0:
optional: true
are-we-there-yet@2.0.0:
dependencies:
delegates: 1.0.0
readable-stream: 3.6.2
optional: true
arg@4.1.3: {}
argparse@1.0.10:
@@ -13741,6 +13641,16 @@ snapshots:
caniuse-lite@1.0.30001704: {}
canvas@2.11.2(encoding@0.1.13):
dependencies:
'@mapbox/node-pre-gyp': 1.0.11(encoding@0.1.13)
nan: 2.22.2
simple-get: 3.1.1
transitivePeerDependencies:
- encoding
- supports-color
optional: true
ccount@2.0.1: {}
chai@4.5.0:
@@ -13938,6 +13848,9 @@ snapshots:
color-name: 1.1.4
simple-swizzle: 0.2.2
color-support@1.1.3:
optional: true
color2k@2.0.3: {}
color@3.2.1:
@@ -14010,6 +13923,9 @@ snapshots:
consola@2.15.3: {}
console-control-strings@1.1.0:
optional: true
content-disposition@0.5.4:
dependencies:
safe-buffer: 5.2.1
@@ -14367,6 +14283,11 @@ snapshots:
dependencies:
character-entities: 2.0.2
decompress-response@4.2.1:
dependencies:
mimic-response: 2.1.0
optional: true
decompress-response@6.0.0:
dependencies:
mimic-response: 3.1.0
@@ -14458,6 +14379,9 @@ snapshots:
delayed-stream@1.0.0: {}
delegates@1.0.0:
optional: true
denque@2.1.0: {}
depd@2.0.0: {}
@@ -15419,6 +15343,19 @@ snapshots:
functions-have-names@1.2.3: {}
gauge@3.0.2:
dependencies:
aproba: 2.0.0
color-support: 1.1.3
console-control-strings: 1.1.0
has-unicode: 2.0.1
object-assign: 4.1.1
signal-exit: 3.0.7
string-width: 4.2.3
strip-ansi: 6.0.1
wide-align: 1.1.5
optional: true
generate-function@2.3.1:
dependencies:
is-property: 1.0.2
@@ -15583,6 +15520,9 @@ snapshots:
dependencies:
has-symbols: 1.1.0
has-unicode@2.0.1:
optional: true
has-yarn@3.0.0: {}
hasown@2.0.2:
@@ -15728,6 +15668,14 @@ snapshots:
quick-lru: 5.1.1
resolve-alpn: 1.2.1
https-proxy-agent@5.0.1:
dependencies:
agent-base: 6.0.2
debug: 4.4.0
transitivePeerDependencies:
- supports-color
optional: true
https-proxy-agent@7.0.6:
dependencies:
agent-base: 7.1.3
@@ -16666,7 +16614,7 @@ snapshots:
lexical@0.14.5: {}
lib0@0.2.102:
lib0@0.2.99:
dependencies:
isomorphic.js: 0.2.5
@@ -16939,7 +16887,7 @@ snapshots:
transitivePeerDependencies:
- supports-color
mdast-util-gfm-autolink-literal@2.0.0:
mdast-util-gfm-autolink-literal@2.0.1:
dependencies:
'@types/mdast': 4.0.4
ccount: 2.0.1
@@ -16987,7 +16935,7 @@ snapshots:
mdast-util-gfm@3.1.0:
dependencies:
mdast-util-from-markdown: 2.0.2
mdast-util-gfm-autolink-literal: 2.0.0
mdast-util-gfm-autolink-literal: 2.0.1
mdast-util-gfm-footnote: 2.1.0
mdast-util-gfm-strikethrough: 2.0.0
mdast-util-gfm-table: 2.0.0
@@ -17494,6 +17442,9 @@ snapshots:
mimic-fn@4.0.0: {}
mimic-response@2.1.0:
optional: true
mimic-response@3.1.0: {}
mimic-response@4.0.0: {}
@@ -17717,6 +17668,9 @@ snapshots:
dependencies:
lru-cache: 7.18.3
nan@2.22.2:
optional: true
nanoid@3.3.9: {}
nanoid@5.1.3: {}
@@ -17848,6 +17802,11 @@ snapshots:
non-layered-tidy-tree-layout@2.0.2: {}
nopt@5.0.0:
dependencies:
abbrev: 1.1.1
optional: true
nopt@7.2.1:
dependencies:
abbrev: 2.0.0
@@ -17864,6 +17823,14 @@ snapshots:
dependencies:
path-key: 4.0.0
npmlog@5.0.1:
dependencies:
are-we-there-yet: 2.0.0
console-control-strings: 1.1.0
gauge: 3.0.2
set-blocking: 2.0.0
optional: true
nprogress@0.2.0: {}
nth-check@2.1.1:
@@ -18148,6 +18115,9 @@ snapshots:
path-type@4.0.0: {}
path2d@0.2.2:
optional: true
pathe@1.1.2: {}
pathe@2.0.3: {}
@@ -18156,9 +18126,13 @@ snapshots:
pathval@2.0.0: {}
pdfjs-dist@4.10.38:
pdfjs-dist@4.4.168(encoding@0.1.13):
optionalDependencies:
'@napi-rs/canvas': 0.1.69
canvas: 2.11.2(encoding@0.1.13)
path2d: 0.2.2
transitivePeerDependencies:
- encoding
- supports-color
peek-readable@5.4.2: {}
@@ -19136,6 +19110,13 @@ snapshots:
simple-concat@1.0.1: {}
simple-get@3.1.1:
dependencies:
decompress-response: 4.2.1
once: 1.4.0
simple-concat: 1.0.1
optional: true
simple-get@4.0.1:
dependencies:
decompress-response: 6.0.0
@@ -20081,27 +20062,6 @@ snapshots:
- tsx
- 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):
dependencies:
esbuild: 0.21.5
@@ -20124,6 +20084,20 @@ snapshots:
sass: 1.85.1
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):
dependencies:
'@vitest/expect': 1.6.1
@@ -20197,45 +20171,6 @@ snapshots:
- tsx
- 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: {}
vue@3.5.13(typescript@5.8.2):
@@ -20371,6 +20306,11 @@ snapshots:
siginfo: 2.0.0
stackback: 0.0.2
wide-align@1.1.5:
dependencies:
string-width: 4.2.3
optional: true
widest-line@4.0.1:
dependencies:
string-width: 5.1.2
@@ -20500,7 +20440,7 @@ snapshots:
yjs@13.6.24:
dependencies:
lib0: 0.2.102
lib0: 0.2.99
yn@3.1.1: {}

View File

@@ -1,4 +1,4 @@
packages:
- packages/*
- projects/*
- scripts/icon
- 'packages/*'
- 'projects/*'
- 'scripts/icon'

View File

@@ -83,7 +83,6 @@ const nextConfig = {
serverComponentsExternalPackages: [
'mongoose',
'pg',
'bullmq',
'@zilliz/milvus2-sdk-node',
"tiktoken",
],

View File

@@ -96,8 +96,6 @@ const MobileVoiceInput = ({
const startYRef = useRef(0);
const [isCancel, setIsCancel] = useState(false);
const canvasPosition = canvasRef.current?.getBoundingClientRect();
const maskBottom = canvasPosition ? `${window.innerHeight - canvasPosition.top}px` : '50px';
const handleTouchStart = useCallback(
(e: React.TouchEvent<HTMLDivElement>) => {
@@ -197,7 +195,7 @@ const MobileVoiceInput = ({
position="fixed"
left={0}
right={0}
bottom={maskBottom}
bottom={'50px'}
h={'200px'}
bg="linear-gradient(to top, white, rgba(255, 255, 255, 0.7), rgba(255, 255, 255, 0))"
>
@@ -297,7 +295,7 @@ const VoiceInput = forwardRef<VoiceInputComponentRef, VoiceInputProps>(
}
};
startSpeak(finishWhisperTranscription);
}, [autoTTSResponse, onSendMessage, resetInputVal, startSpeak, whisperConfig?.autoSend]);
}, []);
const onSpeach = useCallback(() => {
if (isPc) {
@@ -305,7 +303,7 @@ const VoiceInput = forwardRef<VoiceInputComponentRef, VoiceInputProps>(
} else {
setMobilePreSpeak(true);
}
}, [isPc, onStartSpeak]);
}, []);
useImperativeHandle(ref, () => ({
onSpeak: onSpeach
}));

View File

@@ -6,7 +6,6 @@ import {
import { ChatBoxInputType, UserInputFileItemType } from './type';
import { getFileIcon } from '@fastgpt/global/common/file/icon';
import { ChatItemValueTypeEnum, ChatStatusEnum } from '@fastgpt/global/core/chat/constants';
import { extractDeepestInteractive } from '@fastgpt/global/core/workflow/runtime/utils';
export const formatChatValue2InputType = (value?: ChatItemValueItemType[]): ChatBoxInputType => {
if (!value) {
@@ -83,19 +82,17 @@ export const setUserSelectResultToHistories = (
i !== item.value.length - 1 ||
val.type !== ChatItemValueTypeEnum.interactive ||
!val.interactive
) {
)
return val;
}
const finalInteractive = extractDeepestInteractive(val.interactive);
if (finalInteractive.type === 'userSelect') {
if (val.interactive.type === 'userSelect') {
return {
...val,
interactive: {
...finalInteractive,
...val.interactive,
params: {
...finalInteractive.params,
userSelectedVal: finalInteractive.params.userSelectOptions.find(
...val.interactive.params,
userSelectedVal: val.interactive.params.userSelectOptions.find(
(item) => item.value === interactiveVal
)?.value
}
@@ -103,13 +100,13 @@ export const setUserSelectResultToHistories = (
};
}
if (finalInteractive.type === 'userInput') {
if (val.interactive.type === 'userInput') {
return {
...val,
interactive: {
...finalInteractive,
...val.interactive,
params: {
...finalInteractive.params,
...val.interactive.params,
submitted: true
}
}

View File

@@ -28,7 +28,6 @@ import { isEqual } from 'lodash';
import { useTranslation } from 'next-i18next';
import { eventBus, EventNameEnum } from '@/web/common/utils/eventbus';
import { SelectOptionsComponent, FormInputComponent } from './Interactive/InteractiveComponents';
import { extractDeepestInteractive } from '@fastgpt/global/core/workflow/runtime/utils';
const accordionButtonStyle = {
w: 'auto',
@@ -246,12 +245,11 @@ const AIResponseBox = ({
return <RenderTool showAnimation={isChatting} tools={value.tools} />;
}
if (value.type === ChatItemValueTypeEnum.interactive && value.interactive) {
const finalInteractive = extractDeepestInteractive(value.interactive);
if (finalInteractive.type === 'userSelect') {
return <RenderUserSelectInteractive interactive={finalInteractive} />;
if (value.interactive.type === 'userSelect') {
return <RenderUserSelectInteractive interactive={value.interactive} />;
}
if (finalInteractive.type === 'userInput') {
return <RenderUserFormInteractive interactive={finalInteractive} />;
if (value.interactive?.type === 'userInput') {
return <RenderUserFormInteractive interactive={value.interactive} />;
}
}
return null;

View File

@@ -14,7 +14,6 @@ import {
UserSelectInteractive,
UserSelectOptionItemType
} from '@fastgpt/global/core/workflow/template/system/interactive/type';
import MultipleSelect from '@fastgpt/web/components/common/MySelect/MultipleSelect';
const DescriptionBox = React.memo(function DescriptionBox({
description
@@ -174,30 +173,6 @@ export const FormInputComponent = React.memo(function FormInputComponent({
}}
/>
);
case FlowNodeInputTypeEnum.multipleSelect:
return (
<Controller
key={label}
control={control}
name={label}
rules={{ required: required }}
render={({ field: { ref, value } }) => {
if (!list) return <></>;
return (
<MultipleSelect<string>
width={'100%'}
bg={'white'}
py={2}
list={list}
value={value}
isDisabled={submitted}
onSelect={(e) => setValue(label, e)}
isSelectAll={value.length === list.length}
/>
);
}}
/>
);
default:
return null;
}

View File

@@ -1,24 +1,20 @@
import React from 'react';
import { useTranslation } from 'next-i18next';
import { Box, Checkbox, HStack, VStack } from '@chakra-ui/react';
import Avatar from '@fastgpt/web/components/common/Avatar';
import PermissionTags from './PermissionTags';
import { PermissionValueType } from '@fastgpt/global/support/permission/type';
import MyIcon from '@fastgpt/web/components/common/Icon';
import OrgTags from '../../user/team/OrgTags';
import Tag from '@fastgpt/web/components/common/Tag';
function MemberItemCard({
avatar,
key,
onChange: _onChange,
onChange,
isChecked,
onDelete,
name,
permission,
orgs,
addOnly,
rightSlot
orgs
}: {
avatar: string;
key: string;
@@ -27,66 +23,44 @@ function MemberItemCard({
onDelete?: () => void;
name: string;
permission?: PermissionValueType;
addOnly?: boolean;
orgs?: string[];
rightSlot?: React.ReactNode;
}) {
const isAdded = addOnly && !!permission;
const onChange = () => {
if (!isAdded) _onChange();
};
const { t } = useTranslation();
return (
<HStack
justifyContent="space-between"
alignItems="center"
key={key}
px="3"
py="2"
borderRadius="sm"
_hover={{
bgColor: 'myGray.50',
cursor: 'pointer'
}}
onClick={onChange}
>
{isChecked !== undefined && (
<Checkbox isChecked={isChecked} pointerEvents="none" disabled={isAdded} />
)}
<Avatar src={avatar} w="1.5rem" borderRadius={'50%'} />
<>
<HStack
justifyContent="space-between"
alignItems="center"
key={key}
px="3"
py="2"
borderRadius="sm"
_hover={{
bgColor: 'myGray.50',
cursor: 'pointer'
}}
onClick={onChange}
>
{isChecked !== undefined && <Checkbox isChecked={isChecked} pointerEvents="none" />}
<Avatar src={avatar} w="1.5rem" borderRadius={'50%'} />
<Box w="full">
<Box fontSize={'sm'} className="textEllipsis" maxW="300px">
{name}
<Box w="full">
<Box fontSize={'sm'}>{name}</Box>
<Box lineHeight={1}>{orgs && orgs.length > 0 && <OrgTags orgs={orgs} />}</Box>
</Box>
<Box lineHeight={1}>{orgs && orgs.length > 0 && <OrgTags orgs={orgs} />}</Box>
</Box>
{!isAdded && permission && <PermissionTags permission={permission} />}
{isAdded && (
<Tag
mixBlendMode={'multiply'}
colorSchema="blue"
border="none"
py={2}
px={3}
fontSize={'xs'}
>
{t('user:team.collaborator.added')}
</Tag>
)}
{onDelete !== undefined && (
<MyIcon
name="common/closeLight"
w="1rem"
cursor={'pointer'}
_hover={{
color: 'red.600'
}}
onClick={onDelete}
/>
)}
{rightSlot}
</HStack>
{permission && <PermissionTags permission={permission} />}
{onDelete !== undefined && (
<MyIcon
name="common/closeLight"
w="1rem"
cursor={'pointer'}
_hover={{
color: 'red.600'
}}
onClick={onDelete}
/>
)}
</HStack>
</>
);
}

View File

@@ -1,6 +1,17 @@
import { useUserStore } from '@/web/support/user/useUserStore';
import { ChevronDownIcon } from '@chakra-ui/icons';
import { Box, Button, Flex, Grid, HStack, ModalBody, ModalFooter, Text } from '@chakra-ui/react';
import {
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 MyAvatar from '@fastgpt/web/components/common/Avatar';
import MyIcon from '@fastgpt/web/components/common/Icon';
@@ -8,26 +19,27 @@ import SearchInput from '@fastgpt/web/components/common/Input/SearchInput';
import MyModal from '@fastgpt/web/components/common/MyModal';
import { useRequest2 } from '@fastgpt/web/hooks/useRequest';
import { useTranslation } from 'next-i18next';
import { useMemo, useRef, useState } from 'react';
import { useEffect, useMemo, useRef, useState } from 'react';
import PermissionSelect from './PermissionSelect';
import PermissionTags from './PermissionTags';
import {
DEFAULT_ORG_AVATAR,
DEFAULT_TEAM_AVATAR,
DEFAULT_USER_AVATAR
} from '@fastgpt/global/common/system/constants';
import Path from '@/components/common/folder/Path';
import { OrgListItemType } from '@fastgpt/global/support/user/team/org/type';
import { OrgListItemType, OrgType } from '@fastgpt/global/support/user/team/org/type';
import { useContextSelector } from 'use-context-selector';
import { CollaboratorContext } from './context';
import { getTeamMembers } from '@/web/support/user/team/api';
import { getGroupList } from '@/web/support/user/team/group/api';
import { useScrollPagination } from '@fastgpt/web/hooks/useScrollPagination';
import MemberItemCard from './MemberItemCard';
import { GetSearchUserGroupOrg } from '@/web/support/user/api';
import useOrg from '@/web/support/user/team/org/hooks/useOrg';
import { TeamMemberItemType } from '@fastgpt/global/support/user/team/type';
import { MemberGroupListItemType } from '@fastgpt/global/support/permission/memberGroup/type';
import { UpdateClbPermissionProps } from '@fastgpt/global/support/permission/collaborator';
import { ValueOf } from 'next/dist/shared/lib/constants';
import _ from 'lodash';
const HoverBoxStyle = {
bgColor: 'myGray.50',
@@ -119,8 +131,8 @@ function MemberModal({
members: selectedMemberList.map((item) => item.tmbId),
groups: selectedGroupList.map((item) => item._id),
orgs: selectedOrgList.map((item) => item._id),
permission: addOnly ? undefined : selectedPermission!
} as UpdateClbPermissionProps<ValueOf<typeof addOnly>>),
permission: selectedPermission!
}),
{
successToast: t('common:common.Add Success'),
onSuccess() {
@@ -273,7 +285,6 @@ function MemberModal({
const collaborator = collaboratorList?.find((v) => v.tmbId === member.tmbId);
return (
<MemberItemCard
addOnly={addOnly}
avatar={member.avatar}
key={member.tmbId}
name={member.memberName}
@@ -310,33 +321,49 @@ function MemberModal({
};
const collaborator = collaboratorList?.find((v) => v.orgId === org._id);
return (
<MemberItemCard
avatar={org.avatar}
<HStack
justifyContent="space-between"
key={org._id}
name={org.name}
onChange={onChange}
addOnly={addOnly}
permission={collaborator?.permission.value}
isChecked={!!selectedOrgList.find((v) => String(v._id) === String(org._id))}
rightSlot={
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();
}}
/>
)
}
/>
py="2"
px="3"
borderRadius="sm"
alignItems="center"
_hover={HoverBoxStyle}
onClick={onChange}
>
<Checkbox
isChecked={!!selectedOrgList.find((v) => v._id === org._id)}
pointerEvents="none"
/>
<MyAvatar src={org.avatar} w="1.5rem" borderRadius={'50%'} />
<HStack w="full">
<Text>{org.name}</Text>
{org.total && (
<>
<Tag size="sm" my="auto">
{org.total}
</Tag>
</>
)}
</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 ? (
@@ -345,9 +372,6 @@ function MemberModal({
<OrgMemberScrollData>
{Orgs}
{orgMembers.map((member) => {
const isChecked = !!selectedMemberList.find(
(v) => v.tmbId === member.tmbId
);
return (
<MemberItemCard
avatar={member.avatar}
@@ -361,9 +385,7 @@ function MemberModal({
return [...state, member];
});
}}
isChecked={isChecked}
permission={member.permission.value}
addOnly={addOnly && !!member.permission.value}
isChecked={!!selectedMemberList.find((v) => v.tmbId === member.tmbId)}
orgs={member.orgs}
/>
);
@@ -392,7 +414,6 @@ function MemberModal({
permission={collaborator?.permission.value}
onChange={onChange}
isChecked={!!selectedGroupList.find((v) => v._id === group._id)}
addOnly={addOnly}
/>
);
})}

View File

@@ -110,15 +110,7 @@ const CollaboratorContextProvider = ({
} = useRequest2(
async () => {
if (feConfigs.isPlus) {
const data = await onGetCollaboratorList();
return data.map((item) => {
return {
...item,
permission: new Permission({
per: item.permission.value
})
};
});
return onGetCollaboratorList();
}
return [];
},

View File

@@ -10,14 +10,7 @@ function OrgTags({ orgs, type = 'simple' }: { orgs?: string[]; type?: 'simple' |
label={
<VStack gap="1" alignItems={'start'}>
{orgs.map((org, index) => (
<Box
key={index}
fontSize="sm"
fontWeight={400}
color="myGray.500"
maxW={'300px'}
className="textEllipsis"
>
<Box key={index} fontSize="sm" fontWeight={400} color="myGray.500">
{org.slice(1)}
</Box>
))}

View File

@@ -91,7 +91,7 @@ const AccountContainer = ({
}
]
: []),
...(userInfo?.team?.permission.hasApikeyCreatePer
...(userInfo?.team?.permission.hasManagePer
? [
{
icon: 'key',

View File

@@ -5,7 +5,7 @@ import { useTranslation } from 'next-i18next';
import { useForm } from 'react-hook-form';
import { useRequest2 } from '@fastgpt/web/hooks/useRequest';
import { updatePasswordByOld } from '@/web/support/user/api';
import { checkPasswordRule } from '@/web/support/user/login/constants';
import { PasswordRule } from '@/web/support/user/login/constants';
import { useToast } from '@fastgpt/web/hooks/useToast';
type FormType = {
@@ -70,11 +70,9 @@ const UpdatePswModal = ({ onClose }: { onClose: () => void }) => {
placeholder={t('account_info:password_tip')}
{...register('newPsw', {
required: true,
validate: (val) => {
if (!checkPasswordRule(val)) {
return t('login:password_tip');
}
return true;
pattern: {
value: PasswordRule,
message: t('account_info:password_tip')
}
})}
></Input>

View File

@@ -303,7 +303,7 @@ function MemberTable({ Tabs }: { Tabs: React.ReactNode }) {
})()}
</Td>
<Td maxW={'300px'}>
<VStack gap={0} align="start">
<VStack gap={0}>
<Box>{format(new Date(member.createTime), 'yyyy-MM-dd HH:mm:ss')}</Box>
<Box>
{member.updateTime

View File

@@ -1,199 +0,0 @@
import {
Box,
Button,
Flex,
Table,
TableContainer,
Tbody,
Td,
Th,
Thead,
Tr,
HStack
} from '@chakra-ui/react';
import { useState, useEffect, useMemo } from 'react';
import { useTranslation } from 'next-i18next';
import MyBox from '@fastgpt/web/components/common/MyBox';
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';
import MultipleSelect, {
useMultipleSelect
} from '@fastgpt/web/components/common/MySelect/MultipleSelect';
import Avatar from '@fastgpt/web/components/common/Avatar';
import { getTeamMembers } from '@/web/support/user/team/api';
function OperationLogTable({ Tabs }: { Tabs: React.ReactNode }) {
const { t } = useTranslation();
const [searchParams, setSearchParams] = useState<{
tmbIds?: string[];
events?: OperationLogEventEnum[];
}>({});
const { data: members, ScrollData } = useScrollPagination(getTeamMembers, {});
const tmbList = useMemo(
() =>
members.map((item) => ({
label: (
<HStack spacing={1} color={'myGray.500'}>
<Avatar src={item.avatar} w={'1.2rem'} mr={1} rounded={'full'} />
<Box>{item.memberName}</Box>
</HStack>
),
value: item.tmbId
})),
[members]
);
const eventOptions = useMemo(
() =>
Object.values(OperationLogEventEnum).map((event) => ({
label: t(operationLogI18nMap[event].typeLabel),
value: event
})),
[t]
);
const {
data: operationLogs = [],
isLoading: loadingLogs,
ScrollData: LogScrollData
} = useScrollPagination(getOperationLogs, {
pageSize: 20,
refreshDeps: [searchParams],
params: searchParams
});
const {
value: selectedTmbIds,
setValue: setSelectedTmbIds,
isSelectAll: isSelectAllTmb,
setIsSelectAll: setIsSelectAllTmb
} = useMultipleSelect<string>(
tmbList.map((item) => item.value),
true
);
const {
value: selectedEvents,
setValue: setSelectedEvents,
isSelectAll: isSelectAllEvent,
setIsSelectAll: setIsSelectAllEvent
} = useMultipleSelect<OperationLogEventEnum>(
eventOptions.map((item) => item.value),
true
);
useEffect(() => {
setSearchParams({
...(isSelectAllTmb ? {} : { tmbIds: selectedTmbIds }),
...(isSelectAllEvent ? {} : { events: selectedEvents })
});
}, [selectedTmbIds, selectedEvents, isSelectAllTmb, isSelectAllEvent]);
const isLoading = loadingLogs;
return (
<>
<Flex justify={'flex-start'} align={'center'} pb={'1rem'} gap={2} wrap="wrap">
{Tabs}
<Flex alignItems={'center'} gap={2}>
<Box fontSize={'mini'} fontWeight={'medium'} color={'myGray.900'}>
{t('account_team:log_user')}
</Box>
<Box>
<MultipleSelect<string>
list={tmbList}
value={selectedTmbIds}
onSelect={(val) => {
setSelectedTmbIds(val as string[]);
}}
itemWrap={false}
height={'32px'}
bg={'myGray.50'}
w={'160px'}
ScrollData={ScrollData}
isSelectAll={isSelectAllTmb}
setIsSelectAll={setIsSelectAllTmb}
/>
</Box>
</Flex>
<Flex alignItems={'center'} gap={2}>
<Box fontSize={'mini'} fontWeight={'medium'} color={'myGray.900'}>
{t('account_team:log_type')}
</Box>
<Box>
<MultipleSelect
list={eventOptions}
value={selectedEvents}
onSelect={setSelectedEvents}
isSelectAll={isSelectAllEvent}
setIsSelectAll={setIsSelectAllEvent}
itemWrap={false}
height={'32px'}
bg={'myGray.50'}
w={'160px'}
/>
</Box>
</Flex>
</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;

Some files were not shown because too many files have changed in this diff Show More