Compare commits

...

87 Commits

Author SHA1 Message Date
Archer
ee89d0d7a4 Update package.json 2024-07-29 16:00:20 +08:00
Archer
6eeb1b4da1 perf: dataset upload process render (#2191) 2024-07-29 15:58:59 +08:00
Carson Yang
b6c9bb4a65 docs: add subtitle translation example (#2195)
Signed-off-by: Carson Yang <yangchuansheng33@gmail.com>
2024-07-29 15:09:12 +08:00
Archer
20aad33850 fix: plugin revert (#2190) 2024-07-29 11:01:12 +08:00
Archer
02b51317b4 feat: 4.8.8 doc (#2188) 2024-07-29 10:56:29 +08:00
Archer
ba933c7450 perf: markdown code css (#2187) 2024-07-29 10:01:14 +08:00
Archer
856d7ce48f fix: app type (#2185) 2024-07-29 09:47:47 +08:00
Archer
23f22cda18 Add mongo forward read. Fix markdown code block. (#2174)
* perf: read from mongo forward node

* fix: code block ui

* perf: markdown code css
2024-07-29 09:47:30 +08:00
Archer
0a9a7691b4 Update 488.md 2024-07-26 13:50:42 +08:00
Archer
8d25a1d3ec Add img extension (#2172)
* perf: mongo log

* perf: img read

* doc
2024-07-26 12:46:07 +08:00
heheer
2d1e53c3b5 fix: plugin input default value & validate (#2171)
* fix: plugin input default value & validate

* delete console
2024-07-26 12:41:18 +08:00
Finley Ge
71d0093768 fix: app get readable team plugin error (#2169)
In the former code. User who access the plugin should have Write
Permission which should be Read.
2024-07-26 11:43:46 +08:00
Archer
cd554f573e 4.8.8 test fix (#2149)
* perf: code comment

* feat: system plugin input guide

* perf: variable avatar

* feat: feishu webhook

* perf: select tool config tip

* perf: rename variable

* fix: per inherit error

* perf: docker-compose oneapi version and i18n

* perf: ui tip bug

* fix: ts

* perf: pg log

* perf: editor color

* perf: update init
2024-07-26 10:23:44 +08:00
heheer
2d016b7462 fix: editor focus & picker highlight & ui (#2166)
* fix ui

* fix editor focus & picker highlight
2024-07-26 00:03:07 +08:00
Finley Ge
65515e7952 dataset inheritance permission (#2151)
* refactor: dataset create and update api

* chore: defaultpermission & resume fe

* refactor: database auth

* fix(ts): add inheritPermission into default data types

* chore: adjust the code

* fix: list api type filter

* fix: query condition
2024-07-25 19:03:24 +08:00
heheer
5906daff9f fix: plugin run & setting quote variables (#2150)
* fix

* fix

* change variables & variablelabels show condition

* fix type

* fix
2024-07-25 18:01:43 +08:00
Finley Ge
55cefccad1 fix: enable http request (#2159) 2024-07-25 14:39:22 +08:00
Finley Ge
87dac54f1e fix: outlink manage can delete/update others (#2158)
* fix: outlink manage be able to delete/update others

* fix: remove enum validation for teamMemberSchema.
because the old data has the role property, which may cause unknown bug

* perf: change findAndRemove to deleteOne
2024-07-25 13:52:16 +08:00
Archer
45b8d7e8de 4.8.8 test fix (#2143)
* perf: transcriptions api

* perf: variable picker tip

* perf: variable picker tip

* perf: chat select app

* feat: router to app detail

* perf: variable avoid space

* perf: variable picker

* perf: doc2x icon and params

* perf: sandbox support countToken

* feat: sandbox support delay and countToken
2024-07-24 16:02:53 +08:00
Finley Ge
a478621730 refactor openapikey and outlink apis (#2134)
* refactor: OpenAPIKey refactor

* refactor: outlink api refactor

fix: list return wrong data

* chore: remove deprecated type definition

* chore: remove throw Error. instead of Promise.reject

* fix: auth openapikey's owner

* fix: manager could read all keys
2024-07-24 11:11:36 +08:00
heheer
a233ab9584 fix build (#2146) 2024-07-24 11:10:48 +08:00
Menghuan1918
8d2a192515 添加插件:Doc2X 图片/文档识别 (#2097)
* Init the requrest part

* Finish the img deal part

* For test only one plugin

* Finish img2text part

* Finish pdf ocr part

* Change vscode setting back

* Change `for` into` for await` type
2024-07-24 09:59:20 +08:00
heheer
dcaf972767 fix: variable dynamic refresh & space match (#2142)
* fix: variable dynamic refresh & space match

* fix variable picker filter
2024-07-23 22:02:36 +08:00
Zong
f9d43ac009 feat(textSplitter): typo (#2138) 2024-07-23 21:54:55 +08:00
papapatrick
abcf48d5ec perf: switch perf (#2131)
* feat:  新增对话框底部复制按钮

* fix: 对话框底部复制按钮定位问题

* perf: 优化应用切换逻辑

* perf: 删除不必要代码

* fix: 修复编译失败bug&&修复冲突错误

* feat:  新增对话框底部复制按钮

* fix: 对话框底部复制按钮定位问题

* feat: 过长引用折叠功能

* merge: 合并主仓库代码

* refactor:  删除不必要代码

* perf: 优化应用切换逻辑

* perf: 删除不必要代码

* fix: 修复编译失败bug&&修复冲突错误

* merge

* merge: 处理冲突

* refactor: 重构代码删除不必要代码

* perf: 删除不必要代码
2024-07-23 18:53:48 +08:00
heheer
bf5145e632 perf: variable label picker scroll & focus disappear (#2135)
* fix: variable label picker scroll & focus disappear

* fix

* fix filter

* revert
2024-07-23 18:03:53 +08:00
Finley Ge
f37cdabb15 purge old permission (#2118)
* chore: purge old permission
- remove useless role of teamMember
- Cleanup auth apis' Props and Return type Definitions

* chore: a better way of RequireAtLeastOne

Signed-off-by: Finley Ge <m13203533462@163.com>

---------

Signed-off-by: Finley Ge <m13203533462@163.com>
2024-07-23 14:55:54 +08:00
Archer
e99c91aaa6 Perf system plugin and worker (#2126)
* perf: worker pool

* perf: worker register

* perf: worker controller

* perf: system plugin worker

* perf: system plugin worker

* perf: worker

* perf: worker

* worker timeout

* perf: copy icon
2024-07-23 11:23:42 +08:00
heheer
a4787bce5c feat: get node variables in prompt editor (#2087)
* feat: get node variables in prompt editor

* fix

* fix build

* merge

* fix build

* delete default parent

* fix

* fix
2024-07-23 11:20:23 +08:00
jingyang
f24e41f5ec update: i18n common.json keys (#2124) 2024-07-22 20:31:27 +08:00
papapatrick
85de3c1d64 Chat-perf (#2117)
* feat:  新增对话框底部复制按钮

* fix: 对话框底部复制按钮定位问题

* feat: 过长引用折叠功能

* merge: 合并主仓库代码

* refactor: 删除不必要代码

* doc: 文档补充的部分修改成英文
2024-07-22 18:25:25 +08:00
Finley Ge
c6f682310c fix resource permission schema (#2116)
* fix: resource permission schema

* fix: ResorceType
2024-07-22 17:27:48 +08:00
jingyang
991398b8d2 scripts: add delete-unused-keys (#2115)
* scripts: add delete-unused-keys

* update script

* fix keys

* fix ci

* update keys

* add i18n

* update
2024-07-22 15:03:35 +08:00
Archer
f452554663 fix: markdown echarts (#2101)
* fix: markdown echarts

* perf: packages
2024-07-22 10:10:32 +08:00
jingyang
57ff38e16f feat: Optimize i18n keys and remove unused keys, supporting static files in I18nT (#2092)
* feat: packages web i18n

* delete file

* feat:i18n add i18nT

* handle keys

* delete unusedKeys

* fix build

* update dev.md
2024-07-19 16:28:07 +08:00
Archer
f7b55b501f Update 488.md 2024-07-19 14:23:11 +08:00
Archer
cf7145ab54 System plugin (#2091)
* System template (#2082)

* feat: system plugin (#2024)

* add plugin cost & change plugin avatar (#2030)

* add plugin cost & change plugin avatar

* add author

* feat: duckduckgo plugin

* duckduck search

* perf: templates select system plugin

* perf: system plugin avatar

* feat: duckduck plugins

* doc

* perf: plugin classify

* perf: icon avatar component

* perf: system template avatar

---------

Co-authored-by: heheer <71265218+newfish-cmyk@users.noreply.github.com>

* feat: system plugin search

* perf: plugin packages important

* perf: source avatar

* nextconfig

* perf: i18n

* perf: default model

* perf: system plugin author

---------

Co-authored-by: heheer <71265218+newfish-cmyk@users.noreply.github.com>
2024-07-19 14:15:01 +08:00
Carson Yang
1eedb9caba Update workflow to change baseurl for cn site (#2081)
* Docs: fix gitinfo

Signed-off-by: Carson Yang <yangchuansheng33@gmail.com>

* Update workflow to change baseurl for cn site

Signed-off-by: Carson Yang <yangchuansheng33@gmail.com>

---------

Signed-off-by: Carson Yang <yangchuansheng33@gmail.com>
2024-07-18 12:15:03 +08:00
heheer
6390d64417 fix: delete plugin output node check filter (#2080) 2024-07-18 10:44:13 +08:00
Archer
3d80eb288b lock (#2079) 2024-07-18 10:13:47 +08:00
Archer
5cb196535f 4.8.7 fix (#2076) 2024-07-17 19:06:37 +08:00
jingyang
982325d066 fix i18next.d.ts (#2064)
* fix i18next.d.ts

* feat: packages web i18n

* delete file
2024-07-17 15:27:51 +08:00
Archer
36f8755d09 lock (#2063)
* lock

* perf: init data

* perf: vision model url

* fix: chat index
2024-07-17 00:16:57 +08:00
jingyang
fc96bb99cc feat: optimize i18n implementation for better localization (#2062)
* feat: optimize i18n implementation for better localization

* delete i18n-ally-custom-framework.yml

* update common key
2024-07-16 17:56:27 +08:00
papapatrick
1e4ffc2481 docs: 完善本地开发教程 (#2061) 2024-07-16 17:38:11 +08:00
Archer
ee7496467b 4.8.7 test (#2058)
* fix: query extension id;App page change type invalid

* prettier
2024-07-16 16:55:12 +08:00
Archer
b5c98a4f63 Plugin runtime (#2050)
* feat: plugin run (#1950)

* feat: plugin run

* fix

* ui

* fix

* change user input type

* fix

* fix

* temp

* split out plugin chat

* perf: chatbox

* perf: chatbox

* fix: plugin runtime (#2032)

* fix: plugin runtime

* fix

* fix build

* fix build

* perf: chat send prompt

* perf: chat log ux

* perf: chatbox context and share page plugin runtime

* perf: plugin run time config

* fix: ts

* feat: doc

* perf: isPc check

* perf: variable input render

* feat: app search

* fix: response box height

* fix: phone ui

* perf: lock

* perf: plugin route

* fix: chat (#2049)

---------

Co-authored-by: heheer <71265218+newfish-cmyk@users.noreply.github.com>
2024-07-15 22:50:48 +08:00
Zong
090c880860 feat(image): metadata support image mime type (#2026) 2024-07-14 23:25:16 +08:00
Archer
dd2a9bdee5 Update 486.md 2024-07-11 14:43:34 +08:00
Archer
8d60ef505f Update 486.md 2024-07-11 14:41:48 +08:00
Archer
b14514c105 4.8.6 sandbox (#2020)
* fix: openapi doc

* update doc
2024-07-11 14:36:27 +08:00
Archer
11ffaaf2c5 4.8.6 sandbox (#2017)
* fix: openapi doc

* update doc
2024-07-11 10:34:59 +08:00
Archer
e2ae571d15 4.8.6 fix (#1970)
* fix: full text search match query

* perf: mongo schema import, Avoid duplicate import

* feat: mongo log store

* doc

* fix: sandbox outputs

* perf: desc color

* fix: node init

* perf code

* perf: chat header
2024-07-10 15:52:39 +08:00
Zong
f548e24e7d fix(env): typo template (#1990) 2024-07-08 15:05:23 +08:00
Archer
5605f1a892 4.8.6 fix (#1963)
* feat: log store

* fix: full text search match query

* perf: mongo schema import, Avoid duplicate import
2024-07-05 17:37:42 +08:00
Archer
88d10451c9 perf: collection created response (#1947)
* perf: collection created response

* update openapi doc

* remove default collection

* perf: chat ui

* fix: system prompt concat

* perf: published check

* perf: update app
2024-07-05 10:27:38 +08:00
Zong
8a7bd689ae fix(prompt): typo extra content (#1942)
* fix(prompt): typo extra content

* refactor(prompt): AIChat template
2024-07-04 19:08:26 +08:00
Archer
a9cdece341 4.8.6 merge (#1943)
* Dataset collection forbid (#1885)

* perf: tool call support same id

* feat: collection forbid

* feat: collection forbid

* Inheritance Permission for apps (#1897)

* feat: app schema define

chore: references of authapp

* feat: authApp method inheritance

* feat: create and update api

* feat: update

* feat: inheritance Permission controller for app.

* feat: abstract version of inheritPermission

* feat: ancestorId for apps

* chore: update app

* fix: inheritPermission abstract version

* feat: update folder defaultPermission

* feat: app update api

* chore: inheritance frontend

* chore: app list api

* feat: update defaultPermission in app deatil

* feat: backend api finished

* feat: app inheritance permission fe

* fix: app update defaultpermission causes collaborator miss

* fix: ts error

* chore: adjust the codes

* chore: i18n

chore: i18n

* chore: fe adjust and i18n

* chore: adjust the code

* feat: resume api;
chore: rewrite update api and inheritPermission methods

* chore: something

* chore: fe code adjusting

* feat: frontend adjusting

* chore: fe code adjusting

* chore: adjusting the code

* perf: fe loading

* format

* Inheritance fix (#1908)

* fix: SlideCard

* fix: authapp did not return parent app for inheritance app

* fix: fe adjusting

* feat: fe adjusing

* perf: inherit per ux

* doc

* fix: ts errors (#1916)

* perf: inherit permission

* fix: permission inherit

* Workflow type (#1938)

* perf: workflow type

tmp workflow

perf: workflow type

feat: custom field config

* perf: dynamic input

* perf: node classify

* perf: node classify

* perf: node classify

* perf: node classify

* fix: workflow custom input

* feat: text editor and customFeedback move to basic nodes

* feat: community system plugin

* fix: ts

* feat: exprEval plugin

* perf: workflow type

* perf: plugin important

* fix: default templates

* perf: markdown hr css

* lock

* perf: fetch url

* perf: new plugin version

* fix: chat histories update

* fix: collection paths invalid

* perf: app card ui

---------

Co-authored-by: Finley Ge <32237950+FinleyGe@users.noreply.github.com>
2024-07-04 17:42:09 +08:00
Zong
babf03c218 fix(prompt): typo template tag (#1918) 2024-07-04 14:53:46 +08:00
wh0amI
9e169a48e3 Update docker.md (#1910)
* Update docker.md

Fix typo: AUX --> AVX

* Update docker.md

'v' in 'AvX' should be upper case.
2024-07-02 15:43:51 +08:00
江晚
e223390231 添加AI对话时隐藏头部的功能,主要是适配移动端 (#1874) 2024-07-01 11:32:02 +08:00
Archer
3257744c76 Update intro.md 2024-06-30 10:14:02 +08:00
Archer
e1e112eaff Update intro.md 2024-06-30 09:45:59 +08:00
Archer
5c37d29451 Update config.yml 2024-06-28 00:34:25 +08:00
Archer
3a16f1a21c Update README.md 2024-06-28 00:33:14 +08:00
Archer
fa7b73f942 Update 485.md 2024-06-27 15:53:12 +08:00
Archer
f8610d750d Update 484.md 2024-06-27 15:52:53 +08:00
Archer
96a03e9927 4.8.5 test (#1869)
* update upgrade doc

* update upgrade doc
2024-06-27 12:21:05 +08:00
Archer
a3b0ef066b 4.8.5 test fix (#1862)
* app list ui

* feat: photo view

* perf: app dataset filter

* perf: app dataset filter

* fix: chat recently apps

* perf: workflow header phone

* default templates

* default templates

* fix: input guide phone

* fix: i18n

* team chat history

* remove code

* perf: mongo connection

* log level
2024-06-27 10:09:55 +08:00
江晚
9d084b633c 实现在移动端,点击AI回答的图片后,可以通过双指放大缩小移动图片的功能 (#1857) 2024-06-26 16:26:41 +08:00
gaord
4b4bea196a updateUserFeedback api could be authenticated by api key through bearer token as well with more flexibility (#1855) 2024-06-26 16:02:36 +08:00
Archer
e247545afa 4.8.5 perf (#1854)
* update yml

* perf: chat slider

* perf: workflow name

* i18n

* fix: ts

* fix: ts
2024-06-26 12:51:36 +08:00
heheer
93b44fc8f5 fix error toast (#1853) 2024-06-26 11:58:55 +08:00
Archer
9aa6fd4904 4.8.5 perf app ui (#1845)
* list ui and layout

* rename token key

* app ui

* ssr
2024-06-25 19:37:28 +08:00
Archer
c8bc9838e3 feat: app template;fix: chat test reset (#1838)
* feat: app template;fix: chat test reset

* template output

* template output
2024-06-25 13:47:25 +08:00
Archer
5c8c7fb9f2 4.8.5 test fix (#1835)
* faq

* perf: navbar name and fix dataset selector

* feat: app tag

* perf: icon

* fix: update workflow bug

* perf: dataset ui

* perf: menu

* fix: ts

* fix: auth file and app list ui

* app list

* app list

* perf: init api

* update per

* log level
2024-06-25 10:10:24 +08:00
WhiteBottle
d902d29c71 i18n: update Chinese (zh) localization strings (#1827)
* style: add a space between Chinese and alphanumeric characters

在中文和英文、数字之间添加空格,保持中文界面的字符串样式统一

Signed-off-by: WhiteBottle <whitebottle@qq.com>

* style: use fullwidth punctuation in Chinese localization

使用全角标点符号,同时增补/删去部分标点符号,保持中文界面的字符串样式统一

Signed-off-by: WhiteBottle <whitebottle@qq.com>

* fix: standardize spelling of proper nouns and terms and correct typos

规范部分专有名词、术语的拼写与用法,订正错别字

Signed-off-by: WhiteBottle <whitebottle@qq.com>

---------

Signed-off-by: WhiteBottle <whitebottle@qq.com>
2024-06-24 19:31:39 +08:00
Finley Ge
9d29b471bc chore: dataset fe adjusting (#1833) 2024-06-24 19:04:42 +08:00
Finley Ge
4a33e04a08 Dataset frontend style adjusting (#1820)
* feat: dataset controllers

feat: dataset schema

fix: add missing type to dataset schema
Signed-off-by: FinleyGe <m13203533462@163.com>

* chore: use new auth method

Signed-off-by: FinleyGe <m13203533462@163.com>

* feat: finish the dataset permission

fix: ts errors
Signed-off-by: FinleyGe <m13203533462@163.com>

* chore: adjust the code

* chore: adjust the code

* chore: dataset fe adjusting

* fix: double delete confirm

---------

Signed-off-by: FinleyGe <m13203533462@163.com>
2024-06-24 14:58:44 +08:00
Archer
a9ab9ebe8e 4.8.5 test (#1825)
* update model logo

* perf: hide list clb api
2024-06-24 09:29:54 +08:00
Archer
24596a6e21 4.8.5 test (#1819) 2024-06-21 18:32:05 +08:00
Archer
5cc01b8509 4.8.5 test (#1805)
* perf: revert tip

* feat: create copy app

* perf: file stream read

* perf: read directory over 100 files

* perf: index

* fix: team chat api error

* lock

* fix: i18n file
2024-06-21 10:09:00 +08:00
Finley Ge
980b4d3db5 Dataset Permission (#1786)
* feat: dataset controllers

feat: dataset schema

fix: add missing type to dataset schema
Signed-off-by: FinleyGe <m13203533462@163.com>

* feat: dataset list api

Signed-off-by: FinleyGe <m13203533462@163.com>

* chore: all dataset api

Signed-off-by: FinleyGe <m13203533462@163.com>

* feat: new auth dataset method

Signed-off-by: FinleyGe <m13203533462@163.com>

* chore: use new auth method in detail, paths.
feat: add new param defaultPermission to create api

Signed-off-by: FinleyGe <m13203533462@163.com>

* chore: app auth params

Signed-off-by: FinleyGe <m13203533462@163.com>

* chore: use new auth method

Signed-off-by: FinleyGe <m13203533462@163.com>

* feat: new auth collection and file method

Signed-off-by: FinleyGe <m13203533462@163.com>

* chore: dataset collection api new auth

Signed-off-by: FinleyGe <m13203533462@163.com>

* chore: create/*.ts auth

Signed-off-by: FinleyGe <m13203533462@163.com>

* chore: dataset auth

Signed-off-by: FinleyGe <m13203533462@163.com>

* fix: import paths

Signed-off-by: FinleyGe <m13203533462@163.com>

* feat: dataset collaborator

Signed-off-by: FinleyGe <m13203533462@163.com>

* chore: dataset frontend

feat: dataset list frontend

feat: dataset detail
Signed-off-by: FinleyGe <m13203533462@163.com>

* feat: finish the dataset permission

fix: ts errors
Signed-off-by: FinleyGe <m13203533462@163.com>

* fix: empty response of collection api

Signed-off-by: FinleyGe <m13203533462@163.com>

* chore: adjust the code

* chore: adjust the code

* chore: i18n

* fix: ts error

* fix: fe CollectionCard permission

---------

Signed-off-by: FinleyGe <m13203533462@163.com>
2024-06-20 20:52:03 +08:00
powerfool
2b25e3cc2d fix(typo): fixed typo in license (#1800) 2024-06-19 17:06:14 +08:00
Archer
565bfc8486 Concat plugin to app (#1799) 2024-06-19 14:38:21 +08:00
左风
b17d14bb7d doc: update wechat (#1791) 2024-06-18 22:16:05 +08:00
Archer
c11131d653 fix: simple bot dataset load error (#1764) 2024-06-14 12:18:46 +08:00
937 changed files with 46496 additions and 29943 deletions

View File

@@ -1,5 +1,5 @@
blank_issues_enabled: false
contact_links:
- name: 微信交流
url: https://oss.laf.run/htr4n1-images/fastgpt-qr-code.jpg
- name: 飞书话题
url: https://oss.laf.run/otnvvf-imgs/1719505774252.jpg
about: FastGPT 全是问题群

View File

@@ -10,6 +10,7 @@ jobs:
build-fastgpt-sandbox-images:
runs-on: ubuntu-20.04
steps:
# install env
- name: Checkout
uses: actions/checkout@v3
with:
@@ -30,22 +31,53 @@ jobs:
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.GH_PAT }}
- name: Set DOCKER_REPO_TAGGED based on branch or tag
- 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 "DOCKER_REPO_TAGGED=ghcr.io/${{ github.repository_owner }}/fastgpt-sandbox:latest" >> $GITHUB_ENV
echo "Git_Tag=ghcr.io/${{ github.repository_owner }}/fastgpt-sandbox:latest" >> $GITHUB_ENV
echo "Git_Latest=ghcr.io/${{ github.repository_owner }}/fastgpt-sandbox:latest" >> $GITHUB_ENV
echo "Ali_Tag=${{ secrets.ALI_IMAGE_NAME }}/fastgpt-sandbox:latest" >> $GITHUB_ENV
echo "Ali_Latest=${{ secrets.ALI_IMAGE_NAME }}/fastgpt-sandbox:latest" >> $GITHUB_ENV
echo "Docker_Hub_Tag=${{ secrets.DOCKER_IMAGE_NAME }}/fastgpt-sandbox:latest" >> $GITHUB_ENV
echo "Docker_Hub_Latest=${{ secrets.DOCKER_IMAGE_NAME }}/fastgpt-sandbox:latest" >> $GITHUB_ENV
else
echo "DOCKER_REPO_TAGGED=ghcr.io/${{ github.repository_owner }}/fastgpt-sandbox:${{ github.ref_name }}" >> $GITHUB_ENV
echo "Git_Tag=ghcr.io/${{ github.repository_owner }}/fastgpt-sandbox:${{ github.ref_name }}" >> $GITHUB_ENV
echo "Git_Latest=ghcr.io/${{ github.repository_owner }}/fastgpt-sandbox:latest" >> $GITHUB_ENV
echo "Ali_Tag=${{ secrets.ALI_IMAGE_NAME }}/fastgpt-sandbox:${{ github.ref_name }}" >> $GITHUB_ENV
echo "Ali_Latest=${{ secrets.ALI_IMAGE_NAME }}/fastgpt-sandbox:latest" >> $GITHUB_ENV
echo "Docker_Hub_Tag=${{ secrets.DOCKER_IMAGE_NAME }}/fastgpt-sandbox:${{ github.ref_name }}" >> $GITHUB_ENV
echo "Docker_Hub_Latest=${{ secrets.DOCKER_IMAGE_NAME }}/fastgpt-sandbox:latest" >> $GITHUB_ENV
fi
- name: Build and publish image for main branch or tag push event
env:
DOCKER_REPO_TAGGED: ${{ env.DOCKER_REPO_TAGGED }}
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: |
docker buildx build \
-f projects/sandbox/Dockerfile \
@@ -55,54 +87,10 @@ jobs:
--push \
--cache-from=type=local,src=/tmp/.buildx-cache \
--cache-to=type=local,dest=/tmp/.buildx-cache \
-t ${DOCKER_REPO_TAGGED} \
-t ${Git_Tag} \
-t ${Git_Latest} \
-t ${Ali_Tag} \
-t ${Ali_Latest} \
-t ${Docker_Hub_Tag} \
-t ${Docker_Hub_Latest} \
.
push-to-ali-hub:
needs: build-fastgpt-sandbox-images
runs-on: ubuntu-20.04
steps:
- name: Checkout code
uses: actions/checkout@v3
- 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: Set DOCKER_REPO_TAGGED based on branch or tag
run: |
if [[ "${{ github.ref_name }}" == "main" ]]; then
echo "IMAGE_TAG=latest" >> $GITHUB_ENV
else
echo "IMAGE_TAG=${{ github.ref_name }}" >> $GITHUB_ENV
fi
- name: Pull image from GitHub Container Registry
run: docker pull ghcr.io/${{ github.repository_owner }}/fastgpt-sandbox:${{env.IMAGE_TAG}}
- name: Tag image with Docker Hub repository name and version tag
run: docker tag ghcr.io/${{ github.repository_owner }}/fastgpt-sandbox:${{env.IMAGE_TAG}} ${{ secrets.ALI_IMAGE_NAME }}/fastgpt-sandbox:${{env.IMAGE_TAG}}
- name: Push image to Docker Hub
run: docker push ${{ secrets.ALI_IMAGE_NAME }}/fastgpt-sandbox:${{env.IMAGE_TAG}}
push-to-docker-hub:
needs: build-fastgpt-sandbox-images
runs-on: ubuntu-20.04
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Login to Docker Hub
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKER_HUB_NAME }}
password: ${{ secrets.DOCKER_HUB_PASSWORD }}
- name: Set DOCKER_REPO_TAGGED based on branch or tag
run: |
if [[ "${{ github.ref_name }}" == "main" ]]; then
echo "IMAGE_TAG=latest" >> $GITHUB_ENV
else
echo "IMAGE_TAG=${{ github.ref_name }}" >> $GITHUB_ENV
fi
- name: Pull image from GitHub Container Registry
run: docker pull ghcr.io/${{ github.repository_owner }}/fastgpt-sandbox:${{env.IMAGE_TAG}}
- name: Tag image with Docker Hub repository name and version tag
run: docker tag ghcr.io/${{ github.repository_owner }}/fastgpt-sandbox:${{env.IMAGE_TAG}} ${{ secrets.DOCKER_IMAGE_NAME }}/fastgpt-sandbox:${{env.IMAGE_TAG}}
- name: Push image to Docker Hub
run: docker push ${{ secrets.DOCKER_IMAGE_NAME }}/fastgpt-sandbox:${{env.IMAGE_TAG}}

View File

@@ -16,6 +16,9 @@ jobs:
- name: Checkout
uses: actions/checkout@v4
- name: Change baseURL
run: sed -i 's|^baseURL =.*|baseURL = "https://doc.fastgpt.cn"|g' ./docSite/hugo.toml
- name: Get current date and time
id: datetime
run: echo "datetime=$(date +'%Y%m%d%H%M%S')" >> "$GITHUB_OUTPUT"

View File

@@ -11,6 +11,7 @@ jobs:
build-fastgpt-images:
runs-on: ubuntu-20.04
steps:
# install env
- name: Checkout
uses: actions/checkout@v3
with:
@@ -31,19 +32,45 @@ jobs:
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.GH_PAT }}
- name: Set DOCKER_REPO_TAGGED based on branch or tag
- 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 "DOCKER_REPO_TAGGED=ghcr.io/${{ github.repository_owner }}/fastgpt:latest" >> $GITHUB_ENV
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 "DOCKER_REPO_TAGGED=ghcr.io/${{ github.repository_owner }}/fastgpt:${{ github.ref_name }}" >> $GITHUB_ENV
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: Build and publish image for main branch or tag push event
env:
DOCKER_REPO_TAGGED: ${{ env.DOCKER_REPO_TAGGED }}
@@ -56,56 +83,10 @@ jobs:
--push \
--cache-from=type=local,src=/tmp/.buildx-cache \
--cache-to=type=local,dest=/tmp/.buildx-cache \
-t ${DOCKER_REPO_TAGGED} \
-t ${Git_Tag} \
-t ${Git_Latest} \
-t ${Ali_Tag} \
-t ${Ali_Latest} \
-t ${Docker_Hub_Tag} \
-t ${Docker_Hub_Latest} \
.
push-to-docker-hub:
needs: build-fastgpt-images
runs-on: ubuntu-20.04
if: github.repository == 'labring/FastGPT'
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Login to Docker Hub
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKER_HUB_NAME }}
password: ${{ secrets.DOCKER_HUB_PASSWORD }}
- name: Set DOCKER_REPO_TAGGED based on branch or tag
run: |
if [[ "${{ github.ref_name }}" == "main" ]]; then
echo "IMAGE_TAG=latest" >> $GITHUB_ENV
else
echo "IMAGE_TAG=${{ github.ref_name }}" >> $GITHUB_ENV
fi
- name: Pull image from GitHub Container Registry
run: docker pull ghcr.io/${{ github.repository_owner }}/fastgpt:${{env.IMAGE_TAG}}
- name: Tag image with Docker Hub repository name and version tag
run: docker tag ghcr.io/${{ github.repository_owner }}/fastgpt:${{env.IMAGE_TAG}} ${{ secrets.DOCKER_IMAGE_NAME }}/fastgpt:${{env.IMAGE_TAG}}
- name: Push image to Docker Hub
run: docker push ${{ secrets.DOCKER_IMAGE_NAME }}/fastgpt:${{env.IMAGE_TAG}}
push-to-ali-hub:
needs: build-fastgpt-images
if: github.repository == 'labring/FastGPT'
runs-on: ubuntu-20.04
steps:
- name: Checkout code
uses: actions/checkout@v3
- 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: Set DOCKER_REPO_TAGGED based on branch or tag
run: |
if [[ "${{ github.ref_name }}" == "main" ]]; then
echo "IMAGE_TAG=latest" >> $GITHUB_ENV
else
echo "IMAGE_TAG=${{ github.ref_name }}" >> $GITHUB_ENV
fi
- name: Pull image from GitHub Container Registry
run: docker pull ghcr.io/${{ github.repository_owner }}/fastgpt:${{env.IMAGE_TAG}}
- name: Tag image with Docker Hub repository name and version tag
run: docker tag ghcr.io/${{ github.repository_owner }}/fastgpt:${{env.IMAGE_TAG}} ${{ secrets.ALI_IMAGE_NAME }}/fastgpt:${{env.IMAGE_TAG}}
- name: Push image to Docker Hub
run: docker push ${{ secrets.ALI_IMAGE_NAME }}/fastgpt:${{env.IMAGE_TAG}}

View File

@@ -7,7 +7,7 @@ on:
workflow_dispatch:
jobs:
build-fastgpt-images:
preview-fastgpt-images:
runs-on: ubuntu-20.04
steps:
- name: Checkout

1
.npmrc
View File

@@ -1,2 +1,3 @@
public-hoist-pattern[]=*tiktoken*
public-hoist-pattern[]=*@zilliz/milvus2-sdk-node*
registry=https://registry.npmjs.org/

View File

@@ -3,4 +3,6 @@ dist
**/.DS_Store
node_modules
docSite/
*.md
*.md
cl100l_base.ts

View File

@@ -1,5 +0,0 @@
{
"recommendations": [
"inlang.vs-code-extension"
]
}

View File

@@ -26,13 +26,14 @@ usageMatchRegex:
- "[^\\w\\d]workflowT\\(['\"`]({key})['\"`]"
- "[^\\w\\d]userT\\(['\"`]({key})['\"`]"
- "[^\\w\\d]chatT\\(['\"`]({key})['\"`]"
- "[^\\w\\d]i18nT\\(['\"`]({key})['\"`]"
# A RegEx to set a custom scope range. This scope will be used as a prefix when detecting keys
# and works like how the i18next framework identifies the namespace scope from the
# useTranslation() hook.
# You should unescape RegEx strings in order to fit in the YAML file
# To help with this, you can use https://www.freeformatter.com/json-escape.html
scopeRangeRegex: "useTranslation\\(\\s*\\[?\\s*['\"`](.*?)['\"`]"
scopeRangeRegex: "([^:]+):"
# An array of strings containing refactor templates.
# The "$1" will be replaced by the keypath specified.
@@ -41,6 +42,5 @@ scopeRangeRegex: "useTranslation\\(\\s*\\[?\\s*['\"`](.*?)['\"`]"
# refactorTemplates:
# - i18n.get("$1")
# If set to true, only enables this custom framework (will disable all built-in frameworks)
monopoly: true
monopoly: false

19
.vscode/settings.json vendored
View File

@@ -1,16 +1,27 @@
{
"editor.formatOnSave": true,
"editor.mouseWheelZoom": true,
"editor.defaultFormatter": "esbenp.prettier-vscode",
"prettier.prettierPath": "node_modules/prettier",
"typescript.tsdk": "node_modules/typescript/lib",
"prettier.prettierPath": "",
"i18n-ally.localesPaths": [
"projects/app/i18n",
"packages/web/i18n",
],
"i18n-ally.enabledParsers": [
"json",
"yaml",
"js",
"ts"
],
"i18n-ally.enabledParsers": ["json", "yaml", "js", "ts"],
"i18n-ally.keystyle": "nested",
"i18n-ally.sortKeys": true,
"i18n-ally.keepFulfilled": false,
"i18n-ally.sourceLanguage": "zh", // 根据此语言文件翻译其他语言文件的变量和内容
"i18n-ally.displayLanguage": "zh", // 显示语言
"i18n-ally.extract.targetPickingStrategy": "most-similar-by-key"
"i18n-ally.namespace": true,
"i18n-ally.pathMatcher": "{locale}/{namespaces}.json",
"i18n-ally.extract.targetPickingStrategy": "most-similar-by-key",
"[typescript]": {
"editor.defaultFormatter": "esbenp.prettier-vscode"
}
}

View File

@@ -5,7 +5,7 @@ The FastGPT is licensed under the Apache License 2.0, with the following additio
1. FastGPT is permitted to be used for commercialization. You can use FastGPT as a "backend-as-a-service" for your other applications, or delivering it to enterprises as an application development platform. However, when the following conditions are met, you must contact the producer to obtain a commercial license:
a. Multi-tenant SaaS service: Unless explicitly authorized by FastGPT in writing, you may not use the FastGPT.AI source code to operate a multi-tenant SaaS service that is similar to the FastGPT.
b. LOGO and copyright information: In the process of using FastGPT, you may not remove or moFastGPT the LOGO or copyright information in the FastGPT console.
b. LOGO and copyright information: In the process of using FastGPT, you may not remove or modify the LOGO or copyright information in the FastGPT console.
Please contact yujinlong@sealos.io by email to inquire about licensing matters.

View File

@@ -120,9 +120,9 @@ https://github.com/labring/FastGPT/assets/15308462/7d3a38df-eb0e-4388-9250-2409b
## 🏘️ 社区交流群
wx 扫一下加入
扫码加入飞书话题群 (新开,逐渐弃用微信群)
![](https://oss.laf.run/htr4n1-images/wechat-qr-code.jpg)
![](https://oss.laf.run/otnvvf-imgs/1719505774252.jpg)
<a href="#readme">
<img src="https://img.shields.io/badge/-返回顶部-7d09f1.svg" alt="#" align="right">

72
dev.md
View File

@@ -23,6 +23,77 @@ pnpm dev
make dev name=app
```
Note: If the Node version is >= 20, you need to pass the `--no-node-snapshot` parameter to Node when running `pnpm i`
```sh
NODE_OPTIONS=--no-node-snapshot pnpm i
```
## I18N
### Install i18n-ally Plugin
1. Open the Extensions Marketplace in VSCode, search for and install the `i18n Ally` plugin.
### Code Optimization Examples
#### Fetch Specific Namespace Translations in `getServerSideProps`
```typescript
// pages/yourPage.tsx
export async function getServerSideProps(context: any) {
return {
props: {
currentTab: context?.query?.currentTab || TabEnum.info,
...(await serverSideTranslations(context.locale, ['publish', 'user']))
}
};
}
```
#### Use useTranslation Hook in Page
```typescript
// pages/yourPage.tsx
import { useTranslation } from 'next-i18next';
const YourComponent = () => {
const { t } = useTranslation();
return (
<Button
variant="outline"
size="sm"
mr={2}
onClick={() => setShowSelected(false)}
>
{t('common:close')}
</Button>
);
};
export default YourComponent;
```
#### Handle Static File Translations
```typescript
// utils/i18n.ts
import { i18nT } from '@fastgpt/web/i18n/utils';
const staticContent = {
id: 'simpleChat',
avatar: 'core/workflow/template/aiChat',
name: i18nT('app:template.simple_robot'),
};
export default staticContent;
```
### Standardize Translation Format
- Use the t(namespace:key) format to ensure consistent naming.
- Translation keys should use lowercase letters and underscores, e.g., common.close.
## Build
@@ -37,4 +108,3 @@ docker build -f ./projects/app/Dockerfile -t registry.cn-hangzhou.aliyuncs.com/f
# Make cmd: Build image with proxy
make build name=app image=registry.cn-hangzhou.aliyuncs.com/fastgpt/fastgpt:v4.8.1 proxy=taobao
```

Binary file not shown.

After

Width:  |  Height:  |  Size: 222 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 204 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 220 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 207 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 161 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 197 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 164 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 300 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 136 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 67 KiB

After

Width:  |  Height:  |  Size: 209 KiB

View File

@@ -19,13 +19,15 @@ FastGPT 商业版是基于 FastGPT 开源版的增强版本,增加了一些独
| 应用管理与高级编排 | ✅ | ✅ | ✅ |
| 文档知识库 | ✅ | ✅ | ✅ |
| 外部使用 | ✅ | ✅ | ✅ |
| 最大应用数量 | 500 | 无限制 | 由付费套餐决定 |
| 最大知识库数量(单个知识库内容无限制) | 30 | 无限制 | 由付费套餐决定 |
| 自定义版权信息 | ❌ | ✅ | 设计中 |
| 多租户与支付 | ❌ | ✅ | ✅ |
| 团队空间 | ❌ | ✅ | ✅ |
| 应用发布安全配置 | ❌ | ✅ | ✅ |
| 内容审核 | ❌ | ✅ | ✅ |
| web站点同步 | ❌ | ✅ | ✅ |
| 管理后台 | ❌ | ✅ | |
| 管理后台 | ❌ | ✅ | 不需要 |
| 增强训练模式 | ❌ | ✅ | ✅ |
| 图片知识库 | ❌ | 设计中 | 设计中 |
| 自动规划召回 | ❌ | 设计中 | 设计中 |

View File

@@ -148,6 +148,9 @@ llm模型全部合并
- /imgs/model/openai.svg - OpenAI GPT
- /imgs/model/qwen.svg - 通义千问
- /imgs/model/yi.svg - 零一万物
- /imgs/model/gemini.svg - gemini
- /imgs/model/deepseek.svg - deepseek
- /imgs/model/minimax.svg - minimax
-
## 特殊模型

View File

@@ -11,7 +11,6 @@ weight: 707
![](/imgs/sealos-fastgpt.webp)
{{% alert icon="🤖" context="success" %}}
- MongoDB用于存储除了向量外的各类数据
@@ -105,20 +104,18 @@ brew install orbstack
{{< /tab >}}
{{< /tabs >}}
## 开始部署
### 1. 下载 docker-compose.yml
非 Linux 环境或无法访问外网环境,可手动创建一个目录,并下载配置文件和对应版本的`docker-compose.yml`
非 Linux 环境或无法访问外网环境,可手动创建一个目录,并下载配置文件和对应版本的`docker-compose.yml`在这个文件夹中依据下载的配置文件运行docker若作为本地开发使用推荐`docker-compose-pgvector`版本,并且自行拉取并运行`sandbox``fastgpt`并在docker配置文件中注释掉`sandbox``fastgpt`的部分
- [config.json](https://github.com/labring/FastGPT/blob/main/projects/app/data/config.json)
- [docker-compose.yml](https://github.com/labring/FastGPT/blob/main/files/docker) (注意,不同向量库版本的文件不一样)
{{% alert icon="🤖" context="success" %}}
所有 `docker-compose.yml` 配置文件中 `MongoDB` 为 5.x需要用到AUX指令集部分 CPU 不支持,需手动更改其镜像版本为 4.4.24**需要自己在docker hub下载阿里云镜像没做备份
所有 `docker-compose.yml` 配置文件中 `MongoDB` 为 5.x需要用到AVX指令集部分 CPU 不支持,需手动更改其镜像版本为 4.4.24**需要自己在docker hub下载阿里云镜像没做备份
{{% /alert %}}
@@ -271,7 +268,6 @@ rs.status()
默认是写了OneAPi的连接地址和密钥可以通过修改`docker-compose.yml`fastgpt容器的环境变量实现。
`OPENAI_BASE_URL`API 接口的地址,需要加/v1
`CHAT_API_KEY`API 接口的凭证)。
@@ -315,8 +311,7 @@ docker-compose up -d
1. `docker exec -it fastgpt sh` 进入 FastGPT 容器。
2. 直接输入`env`命令查看所有环境变量。
### 为什么无法连接`本地模型`镜像。
### 为什么无法连接`本地模型`镜像
`docker-compose.yml`中使用了桥接的模式建立了`fastgpt`网络如想通过0.0.0.0或镜像名访问其它镜像,需将其它镜像也加入到网络中。
@@ -363,3 +358,14 @@ mongo连接失败查看mongo的运行状态**对应日志**。
### 无法导出知识库、无法使用语音输入/播报
没配置 SSL 证书,无权使用部分功能。
### 登录提示 Network Error
由于服务初始化错误,系统重启导致。
- 90%是由于配置文件写不对,导致 JSON 解析报错
- 剩下的基本是因为向量数据库连不上
### 如何修改密码
修改`docker-compose.yml`文件中`DEFAULT_ROOT_PSW`并重启即可,密码会自动更新。

View File

@@ -31,7 +31,9 @@ images: []
### 页面崩溃
1. 关闭翻译
2. 检查配置文件是否正常加载,如果没有正常加载会导致缺失系统信息,在某些操作下会导致空指针。95%情况是配置文件不对可以F12打开控制台看具体的空指针情况
2. 检查配置文件是否正常加载,如果没有正常加载会导致缺失系统信息,在某些操作下会导致空指针。
* 95%情况是配置文件不对。会提示 xxx undefined
* 提示`URI malformed`,请 Issue 反馈具体操作和页面,这是由于特殊字符串编码解析报错。
3. 某些api不兼容问题较少
### 开启内容补全后,响应速度变慢

View File

@@ -7,8 +7,7 @@ toc: true
weight: 705
---
本文档介绍了如何设置开发环境以构建和测试 [FastGPT](https://fastgpt.in)。
本文档介绍了如何设置开发环境以构建和测试 [FastGPT](https://fastgpt.in)
## 前置依赖项
@@ -16,13 +15,14 @@ weight: 705
- [Git](http://git-scm.com/)
- [Docker](https://www.docker.com/)(构建镜像)
- [Node.js v18.17 / v20.x](http://nodejs.org)
- [Node.js v18.17 / v20.x](http://nodejs.org)版本尽量一样可以使用nvm管理node版本
- [pnpm](https://pnpm.io/) 版本 8.6.0 (目前官方的开发环境)
- make命令: 根据不同平台,百度安装 (官方是GNU Make 4.3)
## 开始本地开发
{{% alert context="success" %}}
1. 用户默认的时区为 `Asia/Shanghai`,非 linux 环境时候,获取系统时间会异常,本地开发时候,可以将用户的时区调整成 UTC+0
2. 建议先服务器装好**数据库**,再进行本地开发。
{{% /alert %}}
@@ -47,9 +47,10 @@ git clone git@github.com:<github_username>/FastGPT.git
### 3. 安装数据库
第一次开发,需要先部署数据库,建议本地开发可以随便找一台 2C2G 的轻量小数据库实践。数据库部署教程:[Docker 快速部署](/docs/development/docker/)。部署完了,可以本地访问其数据库。
第一次开发,需要先部署数据库,建议本地开发可以随便找一台 2C2G 的轻量小数据库实践或者新建文件夹并配置相关文件用以运行docker。数据库部署教程:[Docker 快速部署](/docs/development/docker/)。部署完了,可以本地访问其数据库。
{{% alert context="warning" %}}
Mongo 数据库需要注意,需要注意在连接地址中增加 `directConnection=true` 参数,才能连接上副本集的数据库。
{{% /alert %}}
### 4. 初始配置
@@ -57,7 +58,7 @@ Mongo 数据库需要注意,需要注意在连接地址中增加 `directConnec
**1. 环境变量**
复制`.env.template`文件,在同级目录下生成一个`.env.local` 文件,修改`.env.local` 里内容才是有效的变量。变量说明见 .env.template
复制`.env.template`文件,在同级目录下生成一个`.env.local` 文件,修改`.env.local` 里内容才是有效的变量。变量说明见 .env.template,主要需要修改`API_KEY`和数据库的地址与端口以及数据库账号的用户名和密码具体配置需要和docker配置文件相同其中用户名和密码如需修改需要修改docker配置文件、数据库和`.env.local`文件,不能只改一处。
**2. config 配置文件**
@@ -73,7 +74,7 @@ Mongo 数据库需要注意,需要注意在连接地址中增加 `directConnec
### 5. 运行
可参考项目根目录下的 `dev.md`
可参考项目根目录下的 `dev.md`,第一次编译运行可能会有点慢,需要点耐心哦
```bash
# 给自动化脚本代码执行权限(非 linux 系统, 可以手动执行里面的 postinstall.sh 文件内容)
@@ -114,7 +115,6 @@ make build name=app image=registry.cn-hangzhou.aliyuncs.com/fastgpt/fastgpt:v4.8
如果遇到问题,比如合并冲突或不知道如何打开拉取请求,请查看 GitHub 的[拉取请求教程](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests),了解如何解决合并冲突和其他问题。一旦您的 PR 被合并,您将自豪地被列为[贡献者表](https://github.com/labring/FastGPT/graphs/contributors)中的一员。
## QA
### 本地数据库无法连接
@@ -130,6 +130,7 @@ make build name=app image=registry.cn-hangzhou.aliyuncs.com/fastgpt/fastgpt:v4.8
FastGPT 在`pnpm i`后会执行`postinstall`脚本,用于自动生成`ChakraUI``Type`。如果没有权限,可以先执行`chmod -R +x ./scripts/`,再执行`pnpm i`
仍不可行的话,可以手动执行`./scripts/postinstall.sh`里的内容。
*如果是Windows下的话可以使用git bash给`postinstall`脚本添加执行权限并执行sh脚本*
### TypeError: Cannot read properties of null (reading 'useMemo' )
@@ -141,6 +142,9 @@ FastGPT 在`pnpm i`后会执行`postinstall`脚本,用于自动生成`ChakraUI
4. `cd projects/app`
5. `pnpm dev`
### Error response from daemon: error while creating mount source path 'XXX': mkdir XXX: file exists
这个错误可能是之前停止容器时有文件残留导致的首先需要确认相关镜像都全部关闭然后手动删除相关文件或者重启docker即可
## 加入社区
@@ -155,6 +159,7 @@ FastGPT 在`pnpm i`后会执行`postinstall`脚本,用于自动生成`ChakraUI
FastGPT 使用了 nextjs 的 page route 作为框架。为了区分好前后端代码,在目录分配上会分成 global, service, web 3个自目录分别对应着 `前后端共用``后端专用``前端专用`的代码。
### monorepo
FastGPT 采用 pnpm workspace 方式构建 monorepo 项目,主要分为两个部分:
- projects/app - FastGPT 主项目
@@ -173,6 +178,7 @@ support - 支撑功能(用户体系,计费,鉴权等)
common - 基础功能(日志管理,文件读写等)
{{% details title="代码结构说明" closed="true" %}}
```
.
├── .github // github 相关配置
@@ -200,4 +206,5 @@ common - 基础功能(日志管理,文件读写等)
├── README_ja.md
├── dev.md
```
{{% /details %}}

View File

@@ -7,18 +7,22 @@ toc: true
weight: 852
---
## 发起对话
{{% alert icon="🤖 " context="success" %}}
该接口的 API Key 需使用`应用特定的 key`,否则会报错。
有些包调用时,`BaseUrl`需要添加`v1`路径有些不需要如果出现404情况可补充`v1`重试。
{{% /alert %}}
## 发起对话(简易应用和工作流)
**对话接口兼容`GPT`的接口!如果你的项目使用的是标准的`GPT`官方接口,可以直接通过修改`BaseUrl`和 `Authorization`来访问 FastGpt 应用**
对话接口兼容`GPT`的接口!如果你的项目使用的是标准的`GPT`官方接口,可以直接通过修改`BaseUrl``Authorization`来访问 FastGpt 应用,不过需要注意下面几个规则:
## 请求
{{% alert icon="🤖 " context="success" %}}
* 传入的`model``temperature`等参数字段均无效,这些字段由编排决定。
* 不会返回实际消耗`Token`值,如果需要,可以设置`detail=true`,并手动计算 `responseData` 里的`tokens`值。
{{% /alert %}}
### 请求
{{< tabs tabTotal="2" >}}
{{< tab tabName="请求示例" >}}
@@ -67,7 +71,7 @@ curl --location --request POST 'https://api.fastgpt.in/api/v1/chat/completions'
{{< /tab >}}
{{< /tabs >}}
## 响应
### 响应
{{< tabs tabTotal="5" >}}
{{< tab tabName="detail=false,stream=false 响应" >}}
@@ -245,7 +249,7 @@ data: [{"moduleName":"知识库搜索","moduleType":"datasetSearchNode","running
{{< /markdownify >}}
{{< /tab >}}
{{< tab tabName="detail=true,stream=true 时,event值" >}}
{{< tab tabName="event值" >}}
{{< markdownify >}}
event取值
@@ -265,6 +269,192 @@ event取值
{{< /tabs >}}
## 请求插件
插件的接口与对话接口一致,仅请求参数略有区别,有以下规定:
* 调用插件类型的应用时,接口默认为`detail`模式。
* 无需传入 `chatId`,因为插件只能运行一轮。
* 无需传入`messages`
* 通过传递`variables`来代表插件的输入。
* 通过获取`pluginData`来获取插件输出。
### 请求示例
```bash
curl --location --request POST 'http://localhost:3000/api/v1/chat/completions' \
--header 'Authorization: Bearer test-xxxxx' \
--header 'Content-Type: application/json' \
--data-raw '{
"stream": false,
"chatId": "test",
"variables": {
"query":"你好" # 我的插件输入有一个参数,变量名叫 query
}
}'
```
### 响应示例
{{< tabs tabTotal="3" >}}
{{< tab tabName="detail=true,stream=false 响应" >}}
{{< markdownify >}}
* 插件的输出可以通过查找`responseData`中, `moduleType=pluginOutput`的元素,其`pluginOutput`是插件的输出。
* 流输出,仍可以通过`choices`进行获取。
```json
{
"responseData": [
{
"nodeId": "fdDgXQ6SYn8v",
"moduleName": "AI 对话",
"moduleType": "chatNode",
"totalPoints": 0.685,
"model": "FastAI-3.5",
"tokens": 685,
"query": "你好",
"maxToken": 2000,
"historyPreview": [
{
"obj": "Human",
"value": "你好"
},
{
"obj": "AI",
"value": "你好!有什么可以帮助你的吗?欢迎向我提问。"
}
],
"contextTotalLen": 14,
"runningTime": 1.73
},
{
"nodeId": "pluginOutput",
"moduleName": "自定义插件输出",
"moduleType": "pluginOutput",
"totalPoints": 0,
"pluginOutput": {
"result": "你好!有什么可以帮助你的吗?欢迎向我提问。"
},
"runningTime": 0
}
],
"newVariables": {
"query": "你好"
},
"id": "safsafsa",
"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
event: flowNodeStatus
data: {"status":"running","name":"AI 对话"}
event: answer
data: {"id":"","object":"","created":0,"model":"","choices":[{"delta":{"role":"assistant","content":""},"index":0,"finish_reason":null}]}
event: answer
data: {"id":"","object":"","created":0,"model":"","choices":[{"delta":{"role":"assistant","content":"你"},"index":0,"finish_reason":null}]}
event: answer
data: {"id":"","object":"","created":0,"model":"","choices":[{"delta":{"role":"assistant","content":"好"},"index":0,"finish_reason":null}]}
event: answer
data: {"id":"","object":"","created":0,"model":"","choices":[{"delta":{"role":"assistant","content":""},"index":0,"finish_reason":null}]}
event: answer
data: {"id":"","object":"","created":0,"model":"","choices":[{"delta":{"role":"assistant","content":"有"},"index":0,"finish_reason":null}]}
event: answer
data: {"id":"","object":"","created":0,"model":"","choices":[{"delta":{"role":"assistant","content":"什"},"index":0,"finish_reason":null}]}
event: answer
data: {"id":"","object":"","created":0,"model":"","choices":[{"delta":{"role":"assistant","content":"么"},"index":0,"finish_reason":null}]}
event: answer
data: {"id":"","object":"","created":0,"model":"","choices":[{"delta":{"role":"assistant","content":"可以"},"index":0,"finish_reason":null}]}
event: answer
data: {"id":"","object":"","created":0,"model":"","choices":[{"delta":{"role":"assistant","content":"帮"},"index":0,"finish_reason":null}]}
event: answer
data: {"id":"","object":"","created":0,"model":"","choices":[{"delta":{"role":"assistant","content":"助"},"index":0,"finish_reason":null}]}
event: answer
data: {"id":"","object":"","created":0,"model":"","choices":[{"delta":{"role":"assistant","content":"你"},"index":0,"finish_reason":null}]}
event: answer
data: {"id":"","object":"","created":0,"model":"","choices":[{"delta":{"role":"assistant","content":"的"},"index":0,"finish_reason":null}]}
event: answer
data: {"id":"","object":"","created":0,"model":"","choices":[{"delta":{"role":"assistant","content":"吗"},"index":0,"finish_reason":null}]}
event: answer
data: {"id":"","object":"","created":0,"model":"","choices":[{"delta":{"role":"assistant","content":""},"index":0,"finish_reason":null}]}
event: answer
data: {"id":"","object":"","created":0,"model":"","choices":[{"delta":{"role":"assistant","content":""},"index":0,"finish_reason":null}]}
event: answer
data: {"id":"","object":"","created":0,"model":"","choices":[{"delta":{},"index":0,"finish_reason":"stop"}]}
event: answer
data: [DONE]
event: flowResponses
data: [{"nodeId":"fdDgXQ6SYn8v","moduleName":"AI 对话","moduleType":"chatNode","totalPoints":0.033,"model":"FastAI-3.5","tokens":33,"query":"你好","maxToken":2000,"historyPreview":[{"obj":"Human","value":"你好"},{"obj":"AI","value":"你好!有什么可以帮助你的吗?"}],"contextTotalLen":2,"runningTime":1.42},{"nodeId":"pluginOutput","moduleName":"自定义插件输出","moduleType":"pluginOutput","totalPoints":0,"pluginOutput":{"result":"你好!有什么可以帮助你的吗?"},"runningTime":0}]
```
{{< /markdownify >}}
{{< /tab >}}
{{< tab tabName="输出获取" >}}
{{< markdownify >}}
event取值
- answer: 返回给客户端的文本(最终会算作回答)
- fastAnswer: 指定回复返回给客户端的文本(最终会算作回答)
- toolCall: 执行工具
- toolParams: 工具参数
- toolResponse: 工具返回
- flowNodeStatus: 运行到的节点状态
- flowResponses: 节点完整响应
- updateVariables: 更新变量
- error: 报错
{{< /markdownify >}}
{{< /tab >}}
{{< /tabs >}}
## 使用案例
- [接入 NextWeb/ChatGPT web 等应用](/docs/use-cases/openapi)

View File

@@ -13,7 +13,7 @@ weight: 853
## 创建训练订单(4.6.9地址发生改动)
## 创建训练订单
{{< tabs tabTotal="2" >}}
{{< tab tabName="请求示例" >}}
@@ -26,6 +26,7 @@ curl --location --request POST 'https://api.fastgpt.in/api/support/wallet/usage/
--header 'Authorization: Bearer {{apikey}}' \
--header 'Content-Type: application/json' \
--data-raw '{
"datasetId": "知识库 ID",
"name": "可选,自定义订单名称,例如:文档训练-fastgpt.docx"
}'
```
@@ -127,8 +128,12 @@ curl --location --request POST 'http://localhost:3000/api/core/dataset/create' \
{{< markdownify >}}
```bash
curl --location --request GET 'http://localhost:3000/api/core/dataset/list?parentId=' \
--header 'Authorization: Bearer {{authorization}}' \
curl --location --request POST 'http://localhost:3000/api/core/dataset/list?parentId=' \
--header 'Authorization: Bearer xxxx' \
--header 'Content-Type: application/json' \
--data-raw '{
"parentId":""
}'
```
{{< /markdownify >}}
@@ -138,7 +143,7 @@ curl --location --request GET 'http://localhost:3000/api/core/dataset/list?paren
{{< markdownify >}}
{{% alert icon=" " context="success" %}}
- parentId - 父级ID不传或为空,代表获取根目录下的知识库
- parentId - 父级ID传空字符串或者null,代表获取根目录下的知识库
{{% /alert %}}
{{< /markdownify >}}

View File

@@ -77,7 +77,7 @@ docker-compose up -d
商业版用户需要执行一个初始化,格式化团队信息。
发起 1 个 HTTP 请求 ({{rootkey}} 替换成环境变量里的 `rootkey`{{host}} 替换成自己域名)
发起 1 个 HTTP 请求 ({{rootkey}} 替换成环境变量里的 `rootkey`{{host}} 替换成商业版域名)
```bash
curl --location --request POST 'https://{{host}}/api/init/v468' \

View File

@@ -1,5 +1,5 @@
---
title: 'V4.8.4'
title: 'V4.8.4(需要初始化)'
description: 'FastGPT V4.8.4 更新说明'
icon: 'upgrade'
draft: false
@@ -35,4 +35,4 @@ curl --location --request POST 'https://{{host}}/api/admin/init/484' \
6. 修复 - 定时执行初始化错误。
7. 修复 - 应用调用传参异常。
8. 修复 - ctrl + cv 复杂节点时nodeId错误。
9. 调整组件库全局theme。
9. 调整组件库全局theme。

View File

@@ -0,0 +1,61 @@
---
title: 'V4.8.5(需要初始化)'
description: 'FastGPT V4.8.5 更新说明'
icon: 'upgrade'
draft: false
toc: true
weight: 819
---
## 升级指南
### 1. 做好数据库备份
### 2. 修改镜像
- fastgpt 镜像 tag 修改成 v4.8.5
- 商业版镜像 tag 修改成 v4.8.5
### 3. 执行初始化
从任意终端,发起 1 个 HTTP 请求。其中 {{rootkey}} 替换成环境变量里的 `rootkey`{{host}} 替换成**FastGPT 域名**。
```bash
curl --location --request POST 'https://{{host}}/api/admin/initv485' \
--header 'rootkey: {{rootkey}}' \
--header 'Content-Type: application/json'
```
会把插件的数据表合并到应用中,插件表不会删除。
------
**商业版用户执行额外的初始化**
从任意终端,发起 1 个 HTTP 请求。其中 {{rootkey}} 替换成环境变量里的 `rootkey`{{host}} 替换成**FastGPT 商业版的域名**
```bash
curl --location --request POST 'https://{{host}}/api/admin/init/485' \
--header 'rootkey: {{rootkey}}' \
--header 'Content-Type: application/json'
```
会重置知识库权限系统。
## V4.8.5 更新说明
1. 新增 - 合并插件和应用,统一成工作台
2. 新增 - 应用创建副本功能
3. 新增 - 应用创建模板
4. 新增 - 支持代码运行结果作为工具输出。
5. 新增 - Markdown 图片输出,支持移动端放大缩放。
6. 优化 - 原文件编码存取
7. 优化 - 知识库删除后,简易模式会过滤掉删除的知识库,避免错误判断。
8. 优化 - 文件夹读取,支持单个文件夹超出 100 个文件
9. 优化 - 问答拆分/手动录入,当有`a`字段时,自动将`q`作为补充索引。
10. 优化 - 对话框页面代码
11. 优化 - 工作流新节点自动增加序号名
12. 修复 - 定时任务无法实际关闭
13. 修复 - 输入引导特殊字符导致正则报错
14. 修复 - 文件包含特殊字符`%`,且为转义时会导致页面崩溃
15. 修复 - 自定义输入选择知识库引用时页面崩溃

View File

@@ -0,0 +1,51 @@
---
title: 'V4.8.6(需要初始化)'
description: 'FastGPT V4.8.6 更新说明'
icon: 'upgrade'
draft: false
toc: true
weight: 818
---
## 升级指南
### 1. 做好数据库备份
### 2. 修改镜像
- fastgpt 镜像 tag 修改成 v4.8.6
- fastgpt-sandbox 镜像 tag 修改成 v4.8.6
- 商业版镜像 tag 修改成 v4.8.6
### 3. 执行初始化
从任意终端,发起 1 个 HTTP 请求。其中 {{rootkey}} 替换成环境变量里的 `rootkey`{{host}} 替换成**FastGPT 域名**。
```bash
curl --location --request POST 'https://{{host}}/api/admin/initv486' \
--header 'rootkey: {{rootkey}}' \
--header 'Content-Type: application/json'
```
会初始化应用的继承权限
-------
## V4.8.6 更新说明
1. 新增 - 应用权限继承
2. 新增 - 知识库支持单个集合禁用功能
3. 新增 - 系统插件模式变更,新增链接读取和数学计算器插件,正式版会更新如何自定义系统插件
4. 新增 - 代码沙盒运行参数
5. 新增 - AI对话时隐藏头部的功能主要是适配移动端
6. 优化 - 文件读取Mongo 默认使用从节点,减轻主节点压力
7. 优化 - 提示词模板
8. 优化 - Mongo model 重复加载
9. 修复 - 创建链接集合未返回 id
10. 修复 - 文档接口说明
11. 修复 - api system 提示合并
12. 修复 - 团队插件目录内的内容无法加载
13. 修复 - 知识库集合目录面包屑无法加载
14. 修复 - Markdown 导出对话异常
15. 修复 - 提示模板结束标签错误
16. 修复 - 文档描述

View File

@@ -0,0 +1,29 @@
---
title: 'V4.8.7'
description: 'FastGPT V4.8.7 更新说明'
icon: 'upgrade'
draft: false
toc: true
weight: 817
---
## 升级指南
### 1. 做好数据库备份
### 2. 修改镜像
- fastgpt 镜像 tag 修改成 v4.8.7
- 商业版镜像 tag 修改成 v4.8.7
-------
## V4.8.7 更新说明
1. 新增 - 插件支持独立运行,发布和日志查看
2. 新增 - 应用搜索
3. 优化 - 对话框代码
4. 优化 - 升级 Dockerfile node 和 pnpm 版本
5. 优化 - local 域名部署,也可以正常使用 vision 模式
6. 修复 - 简易模式无法变更全局变量
7. 修复 - gpt4o 无法同时使用工具和图片

View File

@@ -0,0 +1,51 @@
---
title: 'V4.8.8'
description: 'FastGPT V4.8.8 更新说明'
icon: 'upgrade'
draft: false
toc: true
weight: 816
---
## 升级指南
### 1. 做好数据库备份
### 2. 修改镜像
- fastgpt 镜像 tag 修改成 v4.8.8
- 商业版镜像 tag 修改成 v4.8.8
### 3. 执行初始化
从任意终端,发起 1 个 HTTP 请求。其中 {{rootkey}} 替换成环境变量里的 `rootkey`{{host}} 替换成**FastGPT 域名**。
```bash
curl --location --request POST 'https://{{host}}/api/admin/initv488' \
--header 'rootkey: {{rootkey}}' \
--header 'Content-Type: application/json'
```
会初始化知识库的继承权限
-------
## V4.8.8 更新说明
[点击查看完整更新](https://github.com/labring/FastGPT/releases/tag/v4.8.8)
1. 新增 - 重构系统插件的结构。允许向开源社区 PR 系统插件,具体可见: [如何向 FastGPT 社区提交系统插件](https://fael3z0zfze.feishu.cn/wiki/ERZnw9R26iRRG0kXZRec6WL9nwh)。
2. 新增 - DuckDuckGo 系统插件。
3. 新增 - 飞书 webhook 系统插件。
4. 新增 - 修改变量填写方式。提示词输入框以以及工作流中所有 Textarea 输入框,支持输入 / 唤起变量选择,可直接选择所有上游输出值,无需动态引入。
5. 商业版新增 - 知识库权限继承。
6. 优化 - 移动端快速切换应用交互。
7. 优化 - 节点图标。
8. 优化 - 对话框引用增加额外复制案件,便于复制。增加引用内容折叠。
9. 优化 - OpenAI sdk 升级,并自定义了 whisper 模型接口(未仔细查看 sdk 实现,但 sdk 中 whisper 接口,似乎无法适配一般 fastapi 接口)
10. 修复 - Permission 表声明问题。
11. 修复 - 并行执行节点,运行时间未正确记录。
12. 修复 - 运行详情未正确展示嵌套节点信息。
13. 修复 - 简易模式,首次进入,无法正确获取知识库配置。
14. 修复 - Log debug level 配置无效。
15. 修复 - 插件独立运行时,会将插件输入的值进行变量替换,可能导致后续节点变量异常。

View File

@@ -9,7 +9,7 @@ weight: 506
# FastGPT 三分钟接入微信/企业微信
私人微信和企业微信接入的方式基本一样,不同的地方会刻意指出。
[查看视频教程](https://www.bilibili.com/video/BV1cu411F7FN/?spm_id_from=333.1007.top_right_bar_window_history.content.click&vd_source=903c2b09b7412037c2eddc6a8fb9828b)
[查看视频教程](https://www.bilibili.com/video/BV1rJ4m1w7xk/)
## 创建APIKey
首先找到我们需要接入的应用,然后点击「外部使用」->「API访问」创建一个APIKey并保存。
@@ -27,7 +27,7 @@ weight: 506
## sealos部署服务
[访问sealos](https://cloud.sealos.io/) 登陆进来之后打开「应用管理」-> 「新建应用」。
[访问sealos](https://cloud.sealos.run/) 登陆进来之后打开「应用管理」-> 「新建应用」。
- 应用名:称随便填写
- 镜像名:私人微信填写 aibotk/wechat-assistant 企业微信填写 aibotk/worker-assistant
- cpu和内存建议 1c1g
@@ -38,14 +38,14 @@ weight: 506
![](/imgs/wechat5.png)
这里需要填写个环境变量:
这里需要填写个环境变量:
```
AIBOTK_KEY=微秘书 APIKEY
AIBOTK_SECRET=微秘书 APISECRET
WORK_PRO_TOKEN=你申请的企微 token (企业微信需要填写,私人微信不需要)
```
这里最后两个变量只有部署企业微信才需要,私人微信只需要填写前两个即可
这里最后的企业微信 Token 在微秘书的->会员开通栏目中自行购买
![](/imgs/wechat6.png)
@@ -55,9 +55,7 @@ WORK_PRO_TOKEN=你申请的企微 token (企业微信需要填写,私人
![](/imgs/wechat7.png)
`WORK_PRO_TOKEN` [点击这里](https://tss.rpachat.com/?aff=aibotk)申请 token 然后填入即可。
`WECHATY_PUPPET_SERVICE_AUTHORITY`的值复制过去就可以。
`WORK_PRO_TOKEN` 微秘书的会员中心中自行购买即可。
填写完毕后点右上角「部署」,等待应用状态变为运行中。

View File

@@ -4,7 +4,7 @@ description: '使用 HTTP 模块绘制图片'
icon: 'image'
draft: false
toc: true
weight: 404
weight: 408
---
| | |
@@ -272,7 +272,7 @@ Response:
{
"key": "Authorization",
"type": "string",
"value": "Bearer sk-zsfBsxEU3ApSFGYxF4CdB97e9556412588421823371b9f7b"
"value": "Bearer "
}
],
"label": "",

View File

@@ -4,7 +4,7 @@ description: '利用工具调用模块发送一个飞书webhook通知'
icon: 'image'
draft: false
toc: true
weight: 404
weight: 409
---
该文章展示如何发送一个简单的飞书webhook通知以此类推发送其他类型的通知也可以这么操作。
@@ -26,456 +26,378 @@ weight: 404
{{% details title="编排配置" closed="true" %}}
```json
[
{
"nodeId": "userGuide",
"name": "core.module.template.App system setting",
"intro": "core.app.tip.userGuideTip",
"avatar": "/imgs/workflow/userGuide.png",
"flowNodeType": "userGuide",
"position": {
"x": -92.26884681344463,
"y": 710.9354029649536
{
"nodes": [
{
"nodeId": "userGuide",
"name": "系统配置",
"intro": "可以配置应用的系统参数",
"avatar": "/imgs/workflow/userGuide.png",
"flowNodeType": "userGuide",
"position": {
"x": 303.41163758039283,
"y": -552.297639861266
},
"version": "481",
"inputs": [],
"outputs": []
},
"inputs": [
{
"key": "welcomeText",
"type": "hidden",
"valueType": "string",
"label": "core.app.Welcome Text",
"showTargetInApp": false,
"showTargetInPlugin": false,
"value": "",
"connected": false
{
"nodeId": "workflowStartNodeId",
"name": "流程开始",
"intro": "",
"avatar": "/imgs/workflow/userChatInput.svg",
"flowNodeType": "workflowStart",
"position": {
"x": 529.3935295017156,
"y": 197.114018410347
},
{
"key": "variables",
"type": "hidden",
"valueType": "any",
"label": "core.module.Variable",
"value": [],
"showTargetInApp": false,
"showTargetInPlugin": false,
"connected": false
},
{
"key": "questionGuide",
"valueType": "boolean",
"type": "switch",
"label": "",
"showTargetInApp": false,
"showTargetInPlugin": false,
"value": false,
"connected": false
},
{
"key": "tts",
"type": "hidden",
"valueType": "any",
"label": "",
"showTargetInApp": false,
"showTargetInPlugin": false,
"value": {
"type": "web"
},
"connected": false
}
],
"outputs": []
},
{
"nodeId": "userChatInput",
"name": "core.module.template.Chat entrance",
"intro": "当用户发送一个内容后,流程将会从这个模块开始执行。",
"avatar": "/imgs/workflow/userChatInput.svg",
"flowNodeType": "questionInput",
"position": {
"x": 241.60980819261408,
"y": 1330.9528898009685
},
"inputs": [
{
"key": "userChatInput",
"type": "systemInput",
"valueType": "string",
"label": "core.module.input.label.user question",
"showTargetInApp": false,
"showTargetInPlugin": false,
"connected": false
}
],
"outputs": [
{
"key": "userChatInput",
"label": "core.module.input.label.user question",
"type": "source",
"valueType": "string",
"targets": [
{
"nodeId": "n84rvg",
"key": "userChatInput"
}
]
}
]
},
{
"nodeId": "n84rvg",
"name": "工具调用(实验)",
"intro": "通过AI模型自动选择一个或多个功能块进行调用也可以对插件进行调用。",
"avatar": "/imgs/workflow/tool.svg",
"flowNodeType": "tools",
"showStatus": true,
"position": {
"x": 809.4264785615641,
"y": 873.3971746859133
},
"inputs": [
{
"key": "model",
"type": "settingLLMModel",
"label": "core.module.input.label.aiModel",
"required": true,
"valueType": "string",
"showTargetInApp": false,
"showTargetInPlugin": false,
"llmModelType": "all",
"value": "gpt-3.5-turbo",
"connected": false
},
{
"key": "temperature",
"type": "hidden",
"label": "",
"value": 0,
"valueType": "number",
"min": 0,
"max": 10,
"step": 1,
"showTargetInApp": false,
"showTargetInPlugin": false,
"connected": false
},
{
"key": "maxToken",
"type": "hidden",
"label": "",
"value": 2000,
"valueType": "number",
"min": 100,
"max": 4000,
"step": 50,
"showTargetInApp": false,
"showTargetInPlugin": false,
"connected": false
},
{
"key": "systemPrompt",
"type": "textarea",
"max": 3000,
"valueType": "string",
"label": "core.ai.Prompt",
"description": "core.app.tip.chatNodeSystemPromptTip",
"placeholder": "core.app.tip.chatNodeSystemPromptTip",
"showTargetInApp": true,
"showTargetInPlugin": true,
"connected": false
},
{
"key": "history",
"type": "numberInput",
"label": "core.module.input.label.chat history",
"required": true,
"min": 0,
"max": 30,
"valueType": "chatHistory",
"value": 6,
"showTargetInApp": true,
"showTargetInPlugin": true,
"connected": false
},
{
"key": "userChatInput",
"type": "custom",
"label": "",
"required": true,
"valueType": "string",
"showTargetInApp": true,
"showTargetInPlugin": true,
"connected": true
}
],
"outputs": [
{
"key": "userChatInput",
"label": "core.module.input.label.user question",
"type": "hidden",
"valueType": "string",
"targets": []
},
{
"key": "selectedTools",
"valueType": "tools",
"type": "hidden",
"targets": [
{
"nodeId": "3mbu91",
"key": "selectedTools"
}
]
},
{
"key": "finish",
"label": "",
"description": "",
"valueType": "boolean",
"type": "hidden",
"targets": []
}
]
},
{
"nodeId": "3mbu91",
"name": "HTTP 请求",
"intro": "调用飞书webhook发送一个通知",
"avatar": "/imgs/workflow/http.png",
"flowNodeType": "httpRequest468",
"showStatus": true,
"position": {
"x": 1483.6437630977423,
"y": 798.9716928475544
},
"inputs": [
{
"key": "system_httpMethod",
"type": "custom",
"valueType": "string",
"label": "",
"value": "POST",
"required": true,
"showTargetInApp": false,
"showTargetInPlugin": false,
"connected": false
},
{
"key": "system_httpReqUrl",
"type": "hidden",
"valueType": "string",
"label": "",
"description": "core.module.input.description.Http Request Url",
"placeholder": "https://api.ai.com/getInventory",
"required": false,
"showTargetInApp": false,
"showTargetInPlugin": false,
"value": "这里填写你的飞书机器人地址",
"connected": false
},
{
"key": "system_httpHeader",
"type": "custom",
"valueType": "any",
"value": [],
"label": "",
"description": "core.module.input.description.Http Request Header",
"placeholder": "core.module.input.description.Http Request Header",
"required": false,
"showTargetInApp": false,
"showTargetInPlugin": false,
"connected": false
},
{
"key": "system_httpParams",
"type": "hidden",
"valueType": "any",
"value": [],
"label": "",
"required": false,
"showTargetInApp": false,
"showTargetInPlugin": false,
"connected": false
},
{
"key": "system_httpJsonBody",
"type": "hidden",
"valueType": "any",
"value": "{\r\n \"msg_type\": \"text\",\r\n \"content\": {\r\n \"text\": \"{{text}}\"\r\n }\r\n}",
"label": "",
"required": false,
"showTargetInApp": false,
"showTargetInPlugin": false,
"connected": false
},
{
"key": "DYNAMIC_INPUT_KEY",
"type": "target",
"valueType": "any",
"label": "core.workflow.inputType.dynamicTargetInput",
"description": "core.module.input.description.dynamic input",
"required": false,
"showTargetInApp": false,
"showTargetInPlugin": true,
"hideInApp": true,
"connected": false
},
{
"key": "system_addInputParam",
"type": "addInputParam",
"valueType": "any",
"label": "",
"required": false,
"showTargetInApp": false,
"showTargetInPlugin": false,
"editField": {
"key": true,
"description": true,
"dataType": true
},
"defaultEditField": {
"label": "",
"key": "",
"description": "",
"inputType": "target",
"valueType": "string"
},
"connected": false
},
{
"valueType": "string",
"type": "hidden",
"key": "text",
"label": "text",
"toolDescription": "需要发送的通知内容",
"required": true,
"connected": false
}
],
"outputs": [
{
"key": "httpRawResponse",
"label": "原始响应",
"description": "HTTP请求的原始响应。只能接受字符串或JSON类型响应数据。",
"valueType": "any",
"type": "source",
"targets": [
{
"nodeId": "rzx4mj",
"key": "switch"
},
{
"nodeId": "psdhs1",
"key": "switch"
}
]
},
{
"key": "system_addOutputParam",
"type": "addOutputParam",
"valueType": "any",
"label": "",
"targets": [],
"editField": {
"key": true,
"description": true,
"dataType": true,
"defaultValue": true
},
"defaultEditField": {
"label": "",
"key": "",
"description": "",
"outputType": "source",
"valueType": "string"
"version": "481",
"inputs": [
{
"key": "userChatInput",
"renderTypeList": [
"reference",
"textarea"
],
"valueType": "string",
"label": "用户问题",
"required": true,
"toolDescription": "用户问题"
}
],
"outputs": [
{
"id": "userChatInput",
"key": "userChatInput",
"label": "core.module.input.label.user question",
"valueType": "string",
"type": "static"
}
]
},
{
"nodeId": "u6IAOEssxoZT",
"name": "工具调用",
"intro": "通过AI模型自动选择一个或多个功能块进行调用也可以对插件进行调用。",
"avatar": "/imgs/workflow/tool.svg",
"flowNodeType": "tools",
"showStatus": true,
"position": {
"x": 1003.146243538873,
"y": 48.52327869406625
},
{
"type": "source",
"valueType": "string",
"key": "prompt",
"label": "prompt",
"description": "",
"required": false,
"edit": true,
"editField": {
"key": true,
"description": true,
"dataType": true,
"defaultValue": true
"version": "481",
"inputs": [
{
"key": "model",
"renderTypeList": [
"settingLLMModel",
"reference"
],
"label": "core.module.input.label.aiModel",
"valueType": "string",
"llmModelType": "all",
"value": "gpt-3.5-turbo"
},
"targets": []
}
]
},
{
"nodeId": "rzx4mj",
"name": "工具调用终止",
"intro": "该模块需配置工具调用使用。当该模块被执行时本次工具调用将会强制结束并且不再调用AI针对工具调用结果回答问题。",
"avatar": "/imgs/workflow/toolStop.svg",
"flowNodeType": "stopTool",
"position": {
"x": 2145.5070710160267,
"y": 1306.3581817783079
{
"key": "temperature",
"renderTypeList": [
"hidden"
],
"label": "",
"value": 0,
"valueType": "number",
"min": 0,
"max": 10,
"step": 1
},
{
"key": "maxToken",
"renderTypeList": [
"hidden"
],
"label": "",
"value": 2000,
"valueType": "number",
"min": 100,
"max": 4000,
"step": 50
},
{
"key": "systemPrompt",
"renderTypeList": [
"textarea",
"reference"
],
"max": 3000,
"valueType": "string",
"label": "core.ai.Prompt",
"description": "core.app.tip.chatNodeSystemPromptTip",
"placeholder": "core.app.tip.chatNodeSystemPromptTip"
},
{
"key": "history",
"renderTypeList": [
"numberInput",
"reference"
],
"valueType": "chatHistory",
"label": "core.module.input.label.chat history",
"description": "最多携带多少轮对话记录",
"required": true,
"min": 0,
"max": 50,
"value": 6
},
{
"key": "userChatInput",
"renderTypeList": [
"reference",
"textarea"
],
"valueType": "string",
"label": "用户问题",
"required": true,
"value": [
"workflowStartNodeId",
"userChatInput"
]
}
],
"outputs": [
{
"id": "answerText",
"key": "answerText",
"label": "core.module.output.label.Ai response content",
"description": "core.module.output.description.Ai response content",
"valueType": "string",
"type": "static"
}
]
},
"inputs": [
{
"key": "switch",
"type": "triggerAndFinish",
"label": "",
"description": "core.module.input.description.Trigger",
"valueType": "any",
"showTargetInApp": true,
"showTargetInPlugin": true,
"connected": true
}
],
"outputs": []
},
{
"nodeId": "psdhs1",
"name": "指定回复",
"intro": "该模块可以直接回复一段指定的内容。常用于引导、提示。非字符串内容传入时,会转成字符串进行输出。",
"avatar": "/imgs/workflow/reply.png",
"flowNodeType": "answerNode",
"position": {
"x": 2117.0429459850598,
"y": 1658.4125434513746
},
"inputs": [
{
"key": "switch",
"type": "triggerAndFinish",
"label": "",
"description": "core.module.input.description.Trigger",
"valueType": "any",
"showTargetInApp": true,
"showTargetInPlugin": true,
"connected": true
{
"nodeId": "fvY5hb0K646V",
"name": "工具调用终止",
"intro": "该模块需配置工具调用使用。当该模块被执行时本次工具调用将会强制结束并且不再调用AI针对工具调用结果回答问题。",
"avatar": "/imgs/workflow/toolStop.svg",
"flowNodeType": "stopTool",
"position": {
"x": 2367.838362362707,
"y": 732.355988936165
},
"version": "481",
"inputs": [],
"outputs": []
},
{
"nodeId": "x9rN2a4WnZmt",
"name": "HTTP 请求",
"intro": "向飞书发送一个webhooks通知信息。",
"avatar": "/imgs/workflow/http.png",
"flowNodeType": "httpRequest468",
"showStatus": true,
"position": {
"x": 1623.9214305901633,
"y": 22.777089001645862
},
"version": "486",
"inputs": [
{
"key": "system_addInputParam",
"renderTypeList": [
"addInputParam"
],
"valueType": "dynamic",
"label": "",
"required": false,
"description": "core.module.input.description.HTTP Dynamic Input",
"editField": {
"key": true,
"valueType": true
}
},
{
"valueType": "string",
"renderTypeList": [
"reference"
],
"key": "text",
"label": "text",
"toolDescription": "发送的消息",
"required": true,
"canEdit": true,
"editField": {
"key": true,
"description": true
}
},
{
"key": "system_httpMethod",
"renderTypeList": [
"custom"
],
"valueType": "string",
"label": "",
"value": "POST",
"required": true
},
{
"key": "system_httpReqUrl",
"renderTypeList": [
"hidden"
],
"valueType": "string",
"label": "",
"description": "core.module.input.description.Http Request Url",
"placeholder": "https://api.ai.com/getInventory",
"required": false,
"value": ""
},
{
"key": "system_httpHeader",
"renderTypeList": [
"custom"
],
"valueType": "any",
"value": [],
"label": "",
"description": "core.module.input.description.Http Request Header",
"placeholder": "core.module.input.description.Http Request Header",
"required": false
},
{
"key": "system_httpParams",
"renderTypeList": [
"hidden"
],
"valueType": "any",
"value": [],
"label": "",
"required": false
},
{
"key": "system_httpJsonBody",
"renderTypeList": [
"hidden"
],
"valueType": "any",
"value": "{\r\n \"msg_type\": \"text\",\r\n \"content\": {\r\n \"text\": \"{{text}}\"\r\n }\r\n}",
"label": "",
"required": false
}
],
"outputs": [
{
"id": "system_addOutputParam",
"key": "system_addOutputParam",
"type": "dynamic",
"valueType": "dynamic",
"label": "",
"editField": {
"key": true,
"valueType": true
}
},
{
"id": "error",
"key": "error",
"label": "请求错误",
"description": "HTTP请求错误信息成功时返回空",
"valueType": "object",
"type": "static"
},
{
"id": "httpRawResponse",
"key": "httpRawResponse",
"label": "原始响应",
"required": true,
"description": "HTTP请求的原始响应。只能接受字符串或JSON类型响应数据。",
"valueType": "any",
"type": "static"
}
]
},
{
"nodeId": "aGHGqH2oUupj",
"name": "指定回复",
"intro": "该模块可以直接回复一段指定的内容。常用于引导、提示。非字符串内容传入时,会转成字符串进行输出。",
"avatar": "/imgs/workflow/reply.png",
"flowNodeType": "answerNode",
"position": {
"x": 2350.7077940158674,
"y": 107.32448732713493
},
"version": "481",
"inputs": [
{
"key": "text",
"renderTypeList": [
"textarea",
"reference"
],
"valueType": "any",
"required": true,
"label": "core.module.input.label.Response content",
"description": "core.module.input.description.Response content",
"placeholder": "core.module.input.description.Response content",
"value": "嘻嘻,发送成功"
}
],
"outputs": []
}
],
"edges": [
{
"source": "workflowStartNodeId",
"target": "u6IAOEssxoZT",
"sourceHandle": "workflowStartNodeId-source-right",
"targetHandle": "u6IAOEssxoZT-target-left"
},
{
"source": "u6IAOEssxoZT",
"target": "x9rN2a4WnZmt",
"sourceHandle": "selectedTools",
"targetHandle": "selectedTools"
},
{
"source": "x9rN2a4WnZmt",
"target": "fvY5hb0K646V",
"sourceHandle": "x9rN2a4WnZmt-source-right",
"targetHandle": "fvY5hb0K646V-target-left"
},
{
"source": "x9rN2a4WnZmt",
"target": "aGHGqH2oUupj",
"sourceHandle": "x9rN2a4WnZmt-source-right",
"targetHandle": "aGHGqH2oUupj-target-left"
}
],
"chatConfig": {
"variables": [
{
"key": "text",
"type": "textarea",
"valueType": "any",
"label": "core.module.input.label.Response content",
"description": "core.module.input.description.Response content",
"placeholder": "core.module.input.description.Response content",
"showTargetInApp": true,
"showTargetInPlugin": true,
"value": "笑死发送成功啦",
"connected": false
"id": "txq1ca",
"key": "test",
"label": "测试",
"type": "custom",
"required": true,
"maxLen": 50,
"enums": [
{
"value": ""
}
]
}
],
"outputs": [
{
"key": "finish",
"label": "",
"description": "",
"valueType": "boolean",
"type": "hidden",
"targets": []
}
]
"questionGuide": false,
"scheduledTriggerConfig": {
"cronString": "",
"timezone": "Asia/Shanghai",
"defaultPrompt": ""
},
"_id": "66715d4bf577287d39e35ecf"
}
]
}
```
{{% /details %}}

View File

@@ -4,7 +4,7 @@ description: '利用指定回复,创建固定的开头和结尾'
icon: 'healing'
draft: false
toc: true
weight: 401
weight: 405
---
![](/imgs/demo-fix-evidence1.jpg)

View File

@@ -4,7 +4,7 @@ description: '将 FastGPT 接入谷歌搜索'
icon: 'search'
draft: false
toc: true
weight: 402
weight: 406
---
| | |
@@ -192,7 +192,7 @@ export default async function (ctx: FunctionContext) {
},
{
"nodeId": "NOgbnBzUwDgT",
"name": "工具调用(实验)",
"name": "工具调用",
"intro": "通过AI模型自动选择一个或多个功能块进行调用也可以对插件进行调用。",
"avatar": "/imgs/workflow/tool.svg",
"flowNodeType": "tools",

View File

@@ -4,7 +4,7 @@ description: '展示高级编排操作数据库的能力'
icon: 'database'
draft: false
toc: true
weight: 403
weight: 407
---
| | |
@@ -436,7 +436,7 @@ HTTP模块中需要设置 3 个工具参数:
},
{
"nodeId": "fYxwWym8flYL",
"name": "工具调用(实验)",
"name": "工具调用",
"intro": "通过AI模型自动选择一个或多个功能块进行调用也可以对插件进行调用。",
"avatar": "/imgs/workflow/tool.svg",
"flowNodeType": "tools",

File diff suppressed because it is too large Load Diff

View File

@@ -9,7 +9,7 @@ weight: 301
FastGPT 从 V4 版本开始采用新的交互方式来构建 AI 应用。使用了 Flow 节点编排(工作流)的方式来实现复杂工作流,提高可玩性和扩展性。但同时也提高了上手的门槛,有一定开发背景的用户使用起来会比较容易。
[查看视频教程](https://www.bilibili.com/video/BV1aB4y1Z7Hy/?spm_id_from=333.999.list.card_archive.click&vd_source=903c2b09b7412037c2eddc6a8fb9828b)
[查看视频教程](https://www.bilibili.com/video/BV1is421u7bQ/)
![](/imgs/flow-intro1.png)

View File

@@ -5,6 +5,7 @@ enableEmoji = true
enableGitInfo = false # N.B. .GitInfo does not currently function with git submodule content directories
defaultContentLanguage = 'zh-cn'
defaultContentLanguageInSubdir = false
[languages]
[languages.zh-cn]
title = "FastGPT"

View File

@@ -15,7 +15,7 @@
{{ end }}
<!-- change -->
{{ $repoURL = $repoURL | append "docSite/content" .Site.LanguagePrefix $filePath }}
{{ $repoURL = $repoURL | append "docSite/content" .Site.Language.Lang $filePath }}
{{ $repoURL = delimit $repoURL "/" }}
{{ $editPageURL := replaceRE "(https?://)|(/)+" "$1$2" $repoURL }}

View File

@@ -114,15 +114,15 @@ services:
# fastgpt
sandbox:
container_name: sandbox
image: ghcr.io/labring/fastgpt-sandbox:v4.8.4 # git
# image: registry.cn-hangzhou.aliyuncs.com/fastgpt/fastgpt-sandbox:v4.8.4 # 阿里云
image: ghcr.io/labring/fastgpt-sandbox:latest # git
# image: registry.cn-hangzhou.aliyuncs.com/fastgpt/fastgpt-sandbox:latest # 阿里云
networks:
- fastgpt
restart: always
fastgpt:
container_name: fastgpt
image: ghcr.io/labring/fastgpt:v4.8.4 # git
# image: registry.cn-hangzhou.aliyuncs.com/fastgpt/fastgpt:v4.8.4 # 阿里云
image: ghcr.io/labring/fastgpt:v4.8.8 # git
# image: registry.cn-hangzhou.aliyuncs.com/fastgpt/fastgpt:v4.8.8 # 阿里云
ports:
- 3000:3000
networks:
@@ -156,12 +156,14 @@ services:
- SANDBOX_URL=http://sandbox:3000
# 日志等级: debug, info, warn, error
- LOG_LEVEL=info
- STORE_LOG_LEVEL=warn
volumes:
- ./config.json:/app/data/config.json
# oneapi
mysql:
image: mysql:8.0.36
image: registry.cn-hangzhou.aliyuncs.com/fastgpt/mysql:8.0.36 # 阿里云
# image: mysql:8.0.36
container_name: mysql
restart: always
ports:
@@ -177,7 +179,8 @@ services:
- ./mysql:/var/lib/mysql
oneapi:
container_name: oneapi
image: ghcr.io/songquanpeng/one-api:latest
image: ghcr.io/songquanpeng/one-api:0.6.7
# image: registry.cn-hangzhou.aliyuncs.com/fastgpt/one-api:v0.6.6 # 阿里云
ports:
- 3001:3000
depends_on:

View File

@@ -72,15 +72,15 @@ services:
# fastgpt
sandbox:
container_name: sandbox
image: ghcr.io/labring/fastgpt-sandbox:v4.8.4 # git
# image: registry.cn-hangzhou.aliyuncs.com/fastgpt/fastgpt-sandbox:v4.8.4 # 阿里云
image: ghcr.io/labring/fastgpt-sandbox:latest # git
# image: registry.cn-hangzhou.aliyuncs.com/fastgpt/fastgpt-sandbox:latest # 阿里云
networks:
- fastgpt
restart: always
fastgpt:
container_name: fastgpt
image: ghcr.io/labring/fastgpt:v4.8.4 # git
# image: registry.cn-hangzhou.aliyuncs.com/fastgpt/fastgpt:v4.8.4 # 阿里云
image: ghcr.io/labring/fastgpt:v4.8.8 # git
# image: registry.cn-hangzhou.aliyuncs.com/fastgpt/fastgpt:v4.8.8 # 阿里云
ports:
- 3000:3000
networks:
@@ -113,11 +113,13 @@ services:
- SANDBOX_URL=http://sandbox:3000
# 日志等级: debug, info, warn, error
- LOG_LEVEL=info
- STORE_LOG_LEVEL=warn
volumes:
- ./config.json:/app/data/config.json
# oneapi
mysql:
# image: registry.cn-hangzhou.aliyuncs.com/fastgpt/mysql:8.0.36 # 阿里云
image: mysql:8.0.36
container_name: mysql
restart: always
@@ -134,7 +136,8 @@ services:
- ./mysql:/var/lib/mysql
oneapi:
container_name: oneapi
image: ghcr.io/songquanpeng/one-api:latest
image: ghcr.io/songquanpeng/one-api:0.6.7
# image: registry.cn-hangzhou.aliyuncs.com/fastgpt/one-api:v0.6.6 # 阿里云
ports:
- 3001:3000
depends_on:

View File

@@ -53,15 +53,15 @@ services:
wait $$!
sandbox:
container_name: sandbox
image: ghcr.io/labring/fastgpt-sandbox:v4.8.4 # git
# image: registry.cn-hangzhou.aliyuncs.com/fastgpt/fastgpt-sandbox:v4.8.4 # 阿里云
image: ghcr.io/labring/fastgpt-sandbox:latest # git
# image: registry.cn-hangzhou.aliyuncs.com/fastgpt/fastgpt-sandbox:latest # 阿里云
networks:
- fastgpt
restart: always
fastgpt:
container_name: fastgpt
image: ghcr.io/labring/fastgpt:v4.8.4 # git
# image: registry.cn-hangzhou.aliyuncs.com/fastgpt/fastgpt:v4.8.4 # 阿里云
image: ghcr.io/labring/fastgpt:v4.8.8 # git
# image: registry.cn-hangzhou.aliyuncs.com/fastgpt/fastgpt:v4.8.8 # 阿里云
ports:
- 3000:3000
networks:
@@ -94,12 +94,14 @@ services:
- SANDBOX_URL=http://sandbox:3000
# 日志等级: debug, info, warn, error
- LOG_LEVEL=info
- STORE_LOG_LEVEL=warn
volumes:
- ./config.json:/app/data/config.json
# oneapi
mysql:
image: mysql:8.0.36
image: registry.cn-hangzhou.aliyuncs.com/fastgpt/mysql:8.0.36 # 阿里云
# image: mysql:8.0.36
container_name: mysql
restart: always
ports:
@@ -115,7 +117,8 @@ services:
- ./mysql:/var/lib/mysql
oneapi:
container_name: oneapi
image: ghcr.io/songquanpeng/one-api:latest
image: ghcr.io/songquanpeng/one-api:0.6.7
# image: registry.cn-hangzhou.aliyuncs.com/fastgpt/one-api:v0.6.6 # 阿里云
ports:
- 3001:3000
depends_on:

View File

@@ -9,30 +9,25 @@
"gen:theme-typings": "chakra-cli tokens packages/web/styles/theme.ts --out node_modules/.pnpm/node_modules/@chakra-ui/styled-system/dist/theming.types.d.ts",
"postinstall": "sh ./scripts/postinstall.sh",
"initIcon": "node ./scripts/icon/init.js",
"previewIcon": "node ./scripts/icon/index.js"
"previewIcon": "node ./scripts/icon/index.js",
"checkI18n": "node ./scripts/i18n/delete-unused-keys.js"
},
"devDependencies": {
"@chakra-ui/cli": "^2.4.1",
"husky": "^8.0.3",
"i18next": "23.10.0",
"lint-staged": "^13.2.1",
"next-i18next": "15.2.0",
"lint-staged": "^13.3.0",
"i18next": "23.11.5",
"next-i18next": "15.3.0",
"react-i18next": "14.1.2",
"prettier": "3.2.4",
"react-i18next": "13.5.0",
"zhlint": "^0.7.1"
},
"resolutions": {
"react": "18.3.1",
"react-dom": "18.3.1",
"@types/react": "18.3.0",
"@types/react-dom": "18.3.0"
"zhlint": "^0.7.4"
},
"lint-staged": {
"./**/**/*.{ts,tsx,scss}": "npm run format-code",
"./docSite/**/**/*.md": "npm run format-doc"
},
"engines": {
"node": ">=18.0.0",
"pnpm": ">=8.6.0"
"node": ">=18.16.0",
"pnpm": ">=9.0.0"
}
}
}

View File

@@ -4,7 +4,9 @@ import { ErrType } from '../errorCode';
const startCode = 507000;
export enum CommonErrEnum {
fileNotFound = 'fileNotFound',
unAuthFile = 'unAuthFile'
unAuthFile = 'unAuthFile',
missingParams = 'missingParams',
inheritPermissionError = 'inheritPermissionError'
}
const datasetErr = [
{
@@ -14,6 +16,14 @@ const datasetErr = [
{
statusText: CommonErrEnum.unAuthFile,
message: 'error.unAuthFile'
},
{
statusText: CommonErrEnum.missingParams,
message: 'error.missingParams'
},
{
statusText: CommonErrEnum.inheritPermissionError,
message: 'error.inheritPermissionError'
}
];
export default datasetErr.reduce((acc, cur, index) => {

View File

@@ -2,15 +2,20 @@ import { ErrType } from '../errorCode';
/* dataset: 501000 */
export enum DatasetErrEnum {
unExist = 'unExistDataset',
unAuthDataset = 'unAuthDataset',
unCreateCollection = 'unCreateCollection',
unAuthDatasetCollection = 'unAuthDatasetCollection',
unAuthDatasetData = 'unAuthDatasetData',
unAuthDatasetFile = 'unAuthDatasetFile',
unLinkCollection = 'unLinkCollection'
unLinkCollection = 'unLinkCollection',
invalidVectorModelOrQAModel = 'invalidVectorModelOrQAModel'
}
const datasetErr = [
{
statusText: DatasetErrEnum.unExist,
message: 'core.dataset.error.unExistDataset'
},
{
statusText: DatasetErrEnum.unAuthDataset,
message: 'core.dataset.error.unAuthDataset'
@@ -34,6 +39,10 @@ const datasetErr = [
{
statusText: DatasetErrEnum.unLinkCollection,
message: 'core.dataset.error.unLinkCollection'
},
{
statusText: DatasetErrEnum.invalidVectorModelOrQAModel,
message: 'core.dataset.error.invalidVectorModelOrQAModel'
}
];
export default datasetErr.reduce((acc, cur, index) => {

View File

@@ -3,7 +3,8 @@ import { ErrType } from '../errorCode';
/* dataset: 506000 */
export enum OpenApiErrEnum {
unExist = 'openapiUnExist',
unAuth = 'openapiUnAuth'
unAuth = 'openapiUnAuth',
exceedLimit = 'openapiExceedLimit'
}
const errList = [
{
@@ -13,6 +14,10 @@ const errList = [
{
statusText: OpenApiErrEnum.unAuth,
message: '无权操作该 Api Key'
},
{
statusText: OpenApiErrEnum.exceedLimit,
message: '最多 10 组 API 密钥'
}
];
export default errList.reduce((acc, cur, index) => {

View File

@@ -53,4 +53,5 @@ export const uniqueImageTypeList = Object.entries(mongoImageTypeMap)
export const FolderIcon = 'file/fill/folder';
export const FolderImgUrl = '/imgs/files/folder.svg';
export const HttpPluginImgUrl = '/imgs/app/httpPluginFill.svg';
export const HttpImgUrl = '/imgs/workflow/http.png';

View File

@@ -9,6 +9,7 @@ export type MongoImageSchemaType = {
type: `${MongoImageTypeEnum}`;
metadata?: {
mime?: string; // image mime type.
relatedId?: string; // This id is associated with a set of images
};
};

View File

@@ -144,7 +144,7 @@ const commonSplit = (props: SplitProps): SplitResponse => {
];
}
const isCustomSteep = checkIsCustomStep(step);
const isCustomStep = checkIsCustomStep(step);
const isMarkdownSplit = checkIsMarkdownSplit(step);
const independentChunk = checkIndependentChunk(step);
@@ -154,7 +154,7 @@ const commonSplit = (props: SplitProps): SplitResponse => {
.replace(
reg,
(() => {
if (isCustomSteep) return splitMarker;
if (isCustomStep) return splitMarker;
if (independentChunk) return `${splitMarker}$1`;
return `$1${splitMarker}`;
})()
@@ -350,7 +350,7 @@ export const splitText2Chunks = (props: SplitProps): SplitResponse => {
return commonSplit(props);
});
console.log(Date.now() - start);
return {
chunks: splitResult.map((item) => item.chunks).flat(),
chars: splitResult.reduce((sum, item) => sum + item.chars, 0)

View File

@@ -1,6 +1,7 @@
import dayjs from 'dayjs';
import cronParser from 'cron-parser';
export const formatTime2YMDHMW = (time?: Date) => dayjs(time).format('YYYY-MM-DD HH:mm:ss dddd');
export const formatTime2YMDHM = (time?: Date) =>
time ? dayjs(time).format('YYYY-MM-DD HH:mm') : '';
export const formatTime2YMD = (time?: Date) => (time ? dayjs(time).format('YYYY-MM-DD') : '');

View File

@@ -67,6 +67,14 @@ export const getNanoid = (size = 12) => {
/* Custom text to reg, need to replace special chats */
export const replaceRegChars = (text: string) => text.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
export const getRegQueryStr = (text: string, flags = 'i') => {
const formatText = replaceRegChars(text);
const chars = formatText.split('');
const regexPattern = chars.join('.*');
return new RegExp(regexPattern, flags);
};
/* slice json str */
export const sliceJsonStr = (str: string) => {
str = str.replace(/(\\n|\\)/g, '').replace(/ /g, '');

View File

@@ -32,9 +32,12 @@ export type FastGPTFeConfigsType = {
show_promotion?: boolean;
show_team_chat?: boolean;
concatMd?: string;
docUrl?: string;
chatbotUrl?: string;
openAPIDocUrl?: string;
systemPluginCourseUrl?: string;
systemTitle?: string;
systemDescription?: string;
googleClientVerKey?: string;
@@ -70,9 +73,3 @@ export type SystemEnvType = {
oneapiUrl?: string;
chatApiKey?: string;
};
// declare global {
// var feConfigs: FastGPTFeConfigsType;
// var systemEnv: SystemEnvType;
// var systemInitd: boolean;
// }

View File

@@ -2,8 +2,8 @@ import type { LLMModelItemType, VectorModelItemType } from './model.d';
export const defaultQAModels: LLMModelItemType[] = [
{
model: 'gpt-3.5-turbo',
name: 'gpt-3.5-turbo',
model: 'gpt-4o-mini',
name: 'gpt-4o-mini',
maxContext: 16000,
maxResponse: 16000,
quoteMaxToken: 13000,

View File

@@ -100,7 +100,7 @@ export const Prompt_QuotePromptList: PromptTemplateItem[] = [
<QA>
{{quote}}
</QA>}
</QA>
思考流程:
1. 判断问题是否与 <QA></QA> 标记中的内容有关。
@@ -109,7 +109,12 @@ export const Prompt_QuotePromptList: PromptTemplateItem[] = [
4. 如果有相同的问题,直接输出对应答案。
5. 如果只有相近的问题,请把相近的问题和答案一起输出。
最后,避免提及你是从 QA 获取的知识,只需要回复答案。
回答要求:
- 如果没有相关的问答对,你需要澄清。
- 回答的内容应尽可能与 <QA></QA> 标记中的内容一致。
- 避免提及你是从 QA 获取的知识,只需要回复答案。
- 使用 Markdown 语法优化回答格式。
- 使用与问题相同的语言回答。
问题:"""{{question}}"""`
}

View File

@@ -20,7 +20,7 @@ A2:
<Context>
{{text}}
<Context/>
</Context>
`
};

View File

@@ -3,19 +3,12 @@ import { AppTTSConfigType, AppWhisperConfigType } from './type';
export enum AppTypeEnum {
folder = 'folder',
simple = 'simple',
advanced = 'advanced'
workflow = 'advanced',
plugin = 'plugin',
httpPlugin = 'httpPlugin'
}
export const AppTypeMap = {
[AppTypeEnum.folder]: {
label: 'folder'
},
[AppTypeEnum.simple]: {
label: 'simple'
},
[AppTypeEnum.advanced]: {
label: 'advanced'
}
};
export const AppFolderTypeList = [AppTypeEnum.folder, AppTypeEnum.httpPlugin];
export const defaultTTSConfig: AppTTSConfigType = { type: 'web' };

View File

@@ -0,0 +1,24 @@
import { ParentIdType } from 'common/parentFolder/type';
import { AppSchema } from './type';
import { AppTypeEnum } from './constants';
export type CreateAppProps = {
parentId?: ParentIdType;
name?: string;
avatar?: string;
intro?: string;
type?: AppTypeEnum;
modules: AppSchema['modules'];
edges?: AppSchema['edges'];
};
export type CreateHttpPluginChildrenPros = Omit<CreateAppProps, 'type'> & {
parentId: ParentIdType;
name: string;
intro: string;
avatar: string;
modules: AppSchema['modules'];
edges: AppSchema['edges'];
pluginData: {
pluginUniId: string;
};
};

View File

@@ -2,19 +2,20 @@ import { getNanoid } from '../../../common/string/tools';
import { OpenApiJsonSchema } from './type';
import yaml from 'js-yaml';
import { OpenAPIV3 } from 'openapi-types';
import { PluginTypeEnum } from '../constants';
import { FlowNodeInputItemType, FlowNodeOutputItemType } from '../../workflow/type/io.d';
import { FlowNodeInputItemType, FlowNodeOutputItemType } from '../../workflow/type/io';
import { FlowNodeInputTypeEnum, FlowNodeOutputTypeEnum } from '../../workflow/node/constant';
import { NodeInputKeyEnum, WorkflowIOValueTypeEnum } from '../../workflow/constants';
import { WorkflowIOValueTypeEnum } from '../../workflow/constants';
import { PluginInputModule } from '../../workflow/template/system/pluginInput';
import { PluginOutputModule } from '../../workflow/template/system/pluginOutput';
import { HttpModule468 } from '../../workflow/template/system/http468';
import { HttpNode468 } from '../../workflow/template/system/http468';
import { HttpParamAndHeaderItemType } from '../../workflow/api';
import { CreateOnePluginParams } from '../controller';
import { StoreNodeItemType } from '../../workflow/type';
import { StoreNodeItemType } from '../../workflow/type/node';
import { HttpImgUrl } from '../../../common/file/image/constants';
import SwaggerParser from '@apidevtools/swagger-parser';
import { getHandleId } from '../../../core/workflow/utils';
import { getHandleId } from '../../workflow/utils';
import { CreateHttpPluginChildrenPros } from '../controller';
import { AppTypeEnum } from '../constants';
import type { StoreEdgeItemType } from '../../workflow/type/edge';
export const str2OpenApiSchema = async (yamlStr = ''): Promise<OpenApiJsonSchema> => {
try {
@@ -89,7 +90,7 @@ export const httpApiSchema2Plugins = async ({
parentId: string;
apiSchemaStr?: string;
customHeader?: string;
}): Promise<CreateOnePluginParams[]> => {
}): Promise<CreateHttpPluginChildrenPros[]> => {
const jsonSchema = await str2OpenApiSchema(apiSchemaStr);
const baseUrl = jsonSchema.serverPath;
@@ -115,16 +116,7 @@ export const httpApiSchema2Plugins = async ({
required: param.required,
description: param.description,
toolDescription: param.description,
canEdit: true,
editField: {
key: true,
name: true,
description: true,
required: true,
dataType: true,
inputType: true,
isToolInput: true
}
canEdit: true
};
}) || []),
...(propsKeys?.map((key) => {
@@ -137,16 +129,7 @@ export const httpApiSchema2Plugins = async ({
required: false,
description: prop.description,
toolDescription: prop.description,
canEdit: true,
editField: {
key: true,
name: true,
description: true,
required: true,
dataType: true,
inputType: true,
isToolInput: true
}
canEdit: true
};
}) || [])
];
@@ -185,10 +168,6 @@ export const httpApiSchema2Plugins = async ({
label: param.name,
renderTypeList: [FlowNodeInputTypeEnum.reference],
canEdit: true,
editField: {
key: true,
valueType: true
},
value: [pluginInputId, inputIdMap.get(param.name)]
};
}) || []),
@@ -199,10 +178,6 @@ export const httpApiSchema2Plugins = async ({
label: key,
renderTypeList: [FlowNodeInputTypeEnum.reference],
canEdit: true,
editField: {
key: true,
valueType: true
},
value: [pluginInputId, inputIdMap.get(key)]
};
}) || [])
@@ -270,7 +245,7 @@ export const httpApiSchema2Plugins = async ({
}
/* Combine complete modules */
const modules: StoreNodeItemType[] = [
const nodes: StoreNodeItemType[] = [
{
nodeId: pluginInputId,
name: PluginInputModule.name,
@@ -279,8 +254,8 @@ export const httpApiSchema2Plugins = async ({
flowNodeType: PluginInputModule.flowNodeType,
showStatus: PluginInputModule.showStatus,
position: {
x: 616.4226348688949,
y: -165.05298493910115
x: 473.55206291900333,
y: -145.65080850146154
},
version: PluginInputModule.version,
inputs: pluginInputs,
@@ -294,8 +269,8 @@ export const httpApiSchema2Plugins = async ({
flowNodeType: PluginOutputModule.flowNodeType,
showStatus: PluginOutputModule.showStatus,
position: {
x: 1607.7142331269126,
y: -151.8669210746189
x: 1847.5956872650024,
y: 5.114324648101558
},
version: PluginOutputModule.version,
inputs: [
@@ -307,11 +282,6 @@ export const httpApiSchema2Plugins = async ({
required: false,
description: '',
canEdit: true,
editField: {
key: true,
description: true,
valueType: true
},
value: [httpId, 'httpRawResponse']
}
],
@@ -327,29 +297,18 @@ export const httpApiSchema2Plugins = async ({
},
{
nodeId: httpId,
name: HttpModule468.name,
intro: HttpModule468.intro,
avatar: HttpModule468.avatar,
flowNodeType: HttpModule468.flowNodeType,
name: HttpNode468.name,
intro: HttpNode468.intro,
avatar: HttpNode468.avatar,
flowNodeType: HttpNode468.flowNodeType,
showStatus: true,
position: {
x: 1042.549746602742,
y: -447.77496332641647
x: 1188.947986995841,
y: -473.52694296182904
},
version: HttpModule468.version,
version: HttpNode468.version,
inputs: [
{
key: NodeInputKeyEnum.addInputParam,
renderTypeList: [FlowNodeInputTypeEnum.addInputParam],
valueType: WorkflowIOValueTypeEnum.dynamic,
label: '',
required: false,
description: 'core.module.input.description.HTTP Dynamic Input',
editField: {
key: true,
valueType: true
}
},
HttpNode468.inputs[0],
...httpInputs,
{
key: 'system_httpMethod',
@@ -396,11 +355,11 @@ export const httpApiSchema2Plugins = async ({
required: false
}
],
outputs: HttpModule468.outputs
outputs: HttpNode468.outputs
}
];
const edges = [
const edges: StoreEdgeItemType[] = [
{
source: pluginInputId,
target: httpId,
@@ -420,9 +379,12 @@ export const httpApiSchema2Plugins = async ({
avatar: HttpImgUrl,
intro: item.description,
parentId,
type: PluginTypeEnum.http,
modules,
edges
type: AppTypeEnum.plugin,
modules: nodes,
edges,
pluginData: {
pluginUniId: item.name
}
};
});
};

View File

@@ -0,0 +1,10 @@
import { StoreNodeItemType } from '../../workflow/type/node';
import { FlowNodeInputItemType } from '../../workflow/type/io';
import { FlowNodeTypeEnum } from '../../workflow/node/constant';
export const getPluginInputsFromStoreNodes = (nodes: StoreNodeItemType[]) => {
return nodes.find((node) => node.flowNodeType === FlowNodeTypeEnum.pluginInput)?.inputs || [];
};
export const getPluginRunContent = (e: { pluginInputs: FlowNodeInputItemType[] }) => {
return JSON.stringify(e);
};

View File

@@ -1,4 +1,4 @@
import type { FlowNodeTemplateType, StoreNodeItemType } from '../workflow/type';
import type { FlowNodeTemplateType, StoreNodeItemType } from '../workflow/type/node';
import { AppTypeEnum } from './constants';
import { PermissionTypeEnum } from '../../support/permission/constant';
import { VariableInputEnum } from '../workflow/constants';
@@ -6,7 +6,7 @@ import { SelectedDatasetType } from '../workflow/api';
import { DatasetSearchModeEnum } from '../dataset/constants';
import { TeamTagSchema as TeamTagsSchemaType } from '@fastgpt/global/support/user/team/type.d';
import { StoreEdgeItemType } from '../workflow/type/edge';
import { PermissionValueType } from '../../support/permission/type';
import { PermissionSchemaType, PermissionValueType } from '../../support/permission/type';
import { AppPermission } from '../../support/permission/app/controller';
import { ParentIdType } from '../../common/parentFolder/type';
@@ -21,10 +21,17 @@ export type AppSchema = {
name: string;
avatar: string;
intro: string;
updateTime: number;
updateTime: Date;
modules: StoreNodeItemType[];
edges: StoreEdgeItemType[];
pluginData?: {
nodeVersion?: string;
pluginUniId?: string; // plugin unique id(plugin name)
apiSchemaStr?: string; // api schema string
customHeaders?: string;
};
// App system config
chatConfig: AppChatConfigType;
@@ -33,18 +40,19 @@ export type AppSchema = {
inited?: boolean;
teamTags: string[];
defaultPermission: PermissionValueType;
};
} & PermissionSchemaType;
export type AppListItemType = {
_id: string;
tmbId: string;
name: string;
avatar: string;
intro: string;
type: AppTypeEnum;
defaultPermission: PermissionValueType;
updateTime: Date;
pluginData?: AppSchema['pluginData'];
permission: AppPermission;
};
} & PermissionSchemaType;
export type AppDetailType = AppSchema & {
permission: AppPermission;

View File

@@ -3,30 +3,32 @@ import { FlowNodeTypeEnum } from '../workflow/node/constant';
import { NodeInputKeyEnum, FlowNodeTemplateTypeEnum } from '../workflow/constants';
import type { FlowNodeInputItemType } from '../workflow/type/io.d';
import { getAppChatConfig } from '../workflow/utils';
import { StoreNodeItemType } from '../workflow/type';
import { StoreNodeItemType } from '../workflow/type/node';
import { DatasetSearchModeEnum } from '../dataset/constants';
export const getDefaultAppForm = (): AppSimpleEditFormType => ({
aiSettings: {
model: 'gpt-3.5-turbo',
systemPrompt: '',
temperature: 0,
isResponseAnswerText: true,
maxHistories: 6,
maxToken: 4000
},
dataset: {
datasets: [],
similarity: 0.4,
limit: 1500,
searchMode: DatasetSearchModeEnum.embedding,
usingReRank: false,
datasetSearchUsingExtensionQuery: false,
datasetSearchExtensionBg: ''
},
selectedTools: [],
chatConfig: {}
});
export const getDefaultAppForm = (): AppSimpleEditFormType => {
return {
aiSettings: {
model: 'gpt-4o-mini',
systemPrompt: '',
temperature: 0,
isResponseAnswerText: true,
maxHistories: 6,
maxToken: 4000
},
dataset: {
datasets: [],
similarity: 0.4,
limit: 1500,
searchMode: DatasetSearchModeEnum.embedding,
usingReRank: false,
datasetSearchUsingExtensionQuery: true,
datasetSearchExtensionBg: ''
},
selectedTools: [],
chatConfig: {}
};
};
/* format app nodes to edit form */
export const appWorkflow2Form = ({
@@ -99,7 +101,7 @@ export const appWorkflow2Form = ({
if (!node.pluginId) return;
defaultAppForm.selectedTools.push({
id: node.pluginId,
id: node.nodeId,
pluginId: node.pluginId,
name: node.name,
avatar: node.avatar,

View File

@@ -1,12 +1,11 @@
import { StoreNodeItemType } from '../workflow/type';
import { StoreEdgeItemType } from '../workflow/type/edge';
import { AppChatConfigType } from './type';
import { AppChatConfigType, AppSchema } from './type';
export type AppVersionSchemaType = {
_id: string;
appId: string;
time: Date;
nodes: StoreNodeItemType[];
edges: StoreEdgeItemType[];
chatConfig: AppChatConfigType;
nodes: AppSchema['modules'];
edges: AppSchema['edges'];
chatConfig: AppSchema['chatConfig'];
};

View File

@@ -56,7 +56,10 @@ export const chats2GPTMessages = ({
text: item.text?.content || ''
};
}
if (item.type === 'file' && item.file?.type === ChatFileTypeEnum.image) {
if (
item.type === ChatItemValueTypeEnum.file &&
item.file?.type === ChatFileTypeEnum.image
) {
return {
type: 'image_url',
image_url: {
@@ -64,7 +67,6 @@ export const chats2GPTMessages = ({
}
};
}
return;
})
.filter(Boolean) as ChatCompletionContentPart[];
@@ -166,7 +168,7 @@ export const GPTMessages2Chats = (
} else if (item.type === 'image_url') {
value.push({
//@ts-ignore
type: 'file',
type: ChatItemValueTypeEnum.file,
file: {
type: ChatFileTypeEnum.image,
name: '',
@@ -175,7 +177,6 @@ export const GPTMessages2Chats = (
});
}
});
// @ts-ignore
}
} else if (
obj === ChatRoleEnum.AI &&

View File

@@ -56,7 +56,4 @@ export enum ChatStatusEnum {
finish = 'finish'
}
export const IMG_BLOCK_KEY = 'img-block';
export const FILE_BLOCK_KEY = 'file-block';
export const MARKDOWN_QUOTE_SIGN = 'QUOTE SIGN';

View File

@@ -1,4 +1,4 @@
import { ClassifyQuestionAgentItemType } from '../workflow/type';
import { ClassifyQuestionAgentItemType } from '../workflow/template/system/classifyQuestion/type';
import { SearchDataResponseItemType } from '../dataset/type';
import {
ChatFileTypeEnum,
@@ -13,8 +13,8 @@ import { DispatchNodeResponseKeyEnum } from '../workflow/runtime/constants';
import { AppChatConfigType, AppSchema, VariableItemType } from '../app/type';
import type { AppSchema as AppType } from '@fastgpt/global/core/app/type.d';
import { DatasetSearchModeEnum } from '../dataset/constants';
import { ChatBoxInputType } from '../../../../projects/app/src/components/ChatBox/type';
import { DispatchNodeResponseType } from '../workflow/runtime/type.d';
import { ChatBoxInputType } from '../../../../projects/app/src/components/core/chat/ChatContainer/ChatBox/type';
export type ChatSchema = {
_id: string;
@@ -115,6 +115,7 @@ export type ChatSiteItemType = (UserChatItemType | SystemChatItemType | AIChatIt
status: `${ChatStatusEnum}`;
moduleName?: string;
ttsBuffer?: Uint8Array;
responseData?: ChatHistoryItemResType[];
} & ChatBoxInputType;
/* --------- team chat --------- */

View File

@@ -3,6 +3,17 @@ import { FlowNodeTypeEnum } from '../workflow/node/constant';
import { ChatItemValueTypeEnum, ChatRoleEnum } from './constants';
import { ChatHistoryItemResType, ChatItemType, UserChatItemValueItemType } from './type.d';
// Concat 2 -> 1, and sort by role
export const concatHistories = (histories1: ChatItemType[], histories2: ChatItemType[]) => {
const newHistories = [...histories1, ...histories2];
return newHistories.sort((a, b) => {
if (a.obj === ChatRoleEnum.System) {
return -1;
}
return 1;
});
};
export const getChatTitleFromChatMessage = (message?: ChatItemType, defaultValue = '新对话') => {
// @ts-ignore
const textMsg = message?.value.find((item) => item.type === ChatItemValueTypeEnum.text);
@@ -54,11 +65,12 @@ export const filterPublicNodeResponseData = ({
}: {
flowResponses?: ChatHistoryItemResType[];
}) => {
const filedList = ['quoteList', 'moduleType'];
const filedList = ['quoteList', 'moduleType', 'pluginOutput'];
const filterModuleTypeList: any[] = [
FlowNodeTypeEnum.pluginModule,
FlowNodeTypeEnum.datasetSearchNode,
FlowNodeTypeEnum.tools
FlowNodeTypeEnum.tools,
FlowNodeTypeEnum.pluginOutput
];
return flowResponses
@@ -78,14 +90,22 @@ export const filterPublicNodeResponseData = ({
});
};
export const removeEmptyUserInput = (input: UserChatItemValueItemType[]) => {
return input.filter((item) => {
if (item.type === ChatItemValueTypeEnum.text && !item.text?.content?.trim()) {
return false;
}
if (item.type === ChatItemValueTypeEnum.file && !item.file?.url) {
return false;
}
return true;
});
export const removeEmptyUserInput = (input?: UserChatItemValueItemType[]) => {
return (
input?.filter((item) => {
if (item.type === ChatItemValueTypeEnum.text && !item.text?.content?.trim()) {
return false;
}
if (item.type === ChatItemValueTypeEnum.file && !item.file?.url) {
return false;
}
return true;
}) || []
);
};
export const getPluginOutputsFromChatResponses = (responses: ChatHistoryItemResType[]) => {
const outputs =
responses.find((item) => item.moduleType === FlowNodeTypeEnum.pluginOutput)?.pluginOutput ?? {};
return outputs;
};

View File

@@ -1,20 +1,21 @@
import { DatasetDataIndexItemType, DatasetSchemaType } from './type';
import { TrainingModeEnum, DatasetCollectionTypeEnum } from './constants';
import type { LLMModelItemType } from '../ai/model.d';
import { ParentIdType } from 'common/parentFolder/type';
/* ================= dataset ===================== */
export type DatasetUpdateBody = {
id: string;
parentId?: string;
parentId?: ParentIdType;
name?: string;
avatar?: string;
intro?: string;
permission?: DatasetSchemaType['permission'];
agentModel?: LLMModelItemType;
status?: DatasetSchemaType['status'];
websiteConfig?: DatasetSchemaType['websiteConfig'];
externalReadUrl?: DatasetSchemaType['externalReadUrl'];
defaultPermission?: DatasetSchemaType['defaultPermission'];
};
/* ================= collection ===================== */

View File

@@ -0,0 +1,11 @@
import { UpdateClbPermissionProps } from '../../support/permission/collaborator';
import { PermissionValueType } from '../../support/permission/type';
export type UpdateDatasetCollaboratorBody = UpdateClbPermissionProps & {
datasetId: string;
};
export type DatasetCollaboratorDeleteParams = {
datasetId: string;
tmbId: string;
};

View File

@@ -1,3 +1,4 @@
import { DatasetCollectionTypeEnum, TrainingModeEnum, TrainingTypeMap } from '../constants';
import { CollectionWithDatasetType, DatasetCollectionSchemaType } from '../type';
export const getCollectionSourceData = (
@@ -12,3 +13,13 @@ export const getCollectionSourceData = (
sourceName: collection?.name || ''
};
};
export const checkCollectionIsFolder = (type: DatasetCollectionTypeEnum) => {
return type === DatasetCollectionTypeEnum.folder || type === DatasetCollectionTypeEnum.virtual;
};
export const getTrainingTypeLabel = (type?: TrainingModeEnum) => {
if (!type) return '';
if (!TrainingTypeMap[type]) return '';
return TrainingTypeMap[type].label;
};

View File

@@ -8,22 +8,22 @@ export enum DatasetTypeEnum {
export const DatasetTypeMap = {
[DatasetTypeEnum.folder]: {
icon: 'common/folderFill',
label: 'Folder Dataset',
label: 'folder_dataset',
collectionLabel: 'common.Folder'
},
[DatasetTypeEnum.dataset]: {
icon: 'core/dataset/commonDataset',
label: 'Common Dataset',
label: 'common_dataset',
collectionLabel: 'common.File'
},
[DatasetTypeEnum.websiteDataset]: {
icon: 'core/dataset/websiteDataset',
label: 'Website Dataset',
label: 'website_dataset',
collectionLabel: 'common.Website'
},
[DatasetTypeEnum.externalFile]: {
icon: 'core/dataset/externalDataset',
label: 'External File',
label: 'external_file',
collectionLabel: 'common.File'
}
};

View File

@@ -1,3 +1,4 @@
import { PermissionSchemaType } from '../../support/permission/type';
import type { LLMModelItemType, VectorModelItemType } from '../../core/ai/model.d';
import { PermissionTypeEnum } from '../../support/permission/constant';
import { PushDatasetDataChunkProps } from './api';
@@ -8,31 +9,31 @@ import {
SearchScoreTypeEnum,
TrainingModeEnum
} from './constants';
import { DatasetPermission } from '../../support/permission/dataset/controller';
import { Permission } from '../../support/permission/controller';
/* schema */
export type DatasetSchemaType = {
_id: string;
parentId: string;
parentId?: string;
userId: string;
teamId: string;
tmbId: string;
updateTime: Date;
avatar: string;
name: string;
vectorModel: string;
agentModel: string;
intro: string;
type: DatasetTypeEnum;
type: `${DatasetTypeEnum}`;
status: `${DatasetStatusEnum}`;
permission: `${PermissionTypeEnum}`;
// metadata
websiteConfig?: {
url: string;
selector: string;
};
externalReadUrl?: string;
};
} & PermissionSchemaType;
// } & PermissionSchemaType;
export type DatasetCollectionSchemaType = {
_id: string;
@@ -44,6 +45,7 @@ export type DatasetCollectionSchemaType = {
type: DatasetCollectionTypeEnum;
createTime: Date;
updateTime: Date;
forbid?: boolean;
trainingType: TrainingModeEnum;
chunkSize: number;
@@ -85,6 +87,7 @@ export type DatasetDataSchemaType = {
updateTime: Date;
q: string; // large chunks or question
a: string; // answer or custom content
forbid?: boolean;
fullTextToken: string;
indexes: DatasetDataIndexItemType[];
rebuilding?: boolean;
@@ -127,29 +130,26 @@ export type DatasetSimpleItemType = {
};
export type DatasetListItemType = {
_id: string;
parentId: string;
avatar: string;
name: string;
intro: string;
type: DatasetTypeEnum;
isOwner: boolean;
canWrite: boolean;
permission: `${PermissionTypeEnum}`;
type: `${DatasetTypeEnum}`;
permission: DatasetPermission;
vectorModel: VectorModelItemType;
};
} & PermissionSchemaType;
export type DatasetItemType = Omit<DatasetSchemaType, 'vectorModel' | 'agentModel'> & {
vectorModel: VectorModelItemType;
agentModel: LLMModelItemType;
isOwner: boolean;
canWrite: boolean;
permission: DatasetPermission;
};
/* ================= collection ===================== */
export type DatasetCollectionItemType = CollectionWithDatasetType & {
canWrite: boolean;
sourceName: string;
sourceId?: string;
file?: DatasetFileSchema;
permission: DatasetPermission;
};
/* ================= data ===================== */
@@ -177,10 +177,9 @@ export type DatasetFileSchema = {
filename: string;
contentType: string;
metadata: {
contentType: string;
datasetId: string;
teamId: string;
tmbId: string;
encoding?: string;
};
};

View File

@@ -24,13 +24,15 @@ export function getSourceNameIcon({
sourceName: string;
sourceId?: string;
}) {
const fileIcon = getFileIcon(decodeURIComponent(sourceName), '');
if (fileIcon) {
return fileIcon;
}
if (strIsLink(sourceId)) {
return 'common/linkBlue';
}
try {
const fileIcon = getFileIcon(decodeURIComponent(sourceName.replace(/%/g, '%25')), '');
if (fileIcon) {
return fileIcon;
}
if (strIsLink(sourceId)) {
return 'common/linkBlue';
}
} catch (error) {}
return 'file/fill/manual';
}

View File

@@ -1,5 +1,3 @@
import { StoreNodeItemType } from '../workflow/type';
export enum PluginTypeEnum {
folder = 'folder',
custom = 'custom',

View File

@@ -1,7 +1,7 @@
import { StoreEdgeItemType } from 'core/workflow/type/edge';
import type { StoreNodeItemType } from '../workflow/type';
import type { StoreNodeItemType } from '../workflow/type/node';
import { PluginTypeEnum } from './constants';
import { HttpAuthMethodType } from './httpPlugin/type';
import { HttpAuthMethodType } from '../app/httpPlugin/type';
export type CreateOnePluginParams = {
name: string;

View File

@@ -1,8 +1,9 @@
import { StoreEdgeItemType } from 'core/workflow/type/edge';
import { ModuleTemplateTypeEnum } from '../workflow/constants';
import type { FlowModuleTemplateType, StoreNodeItemType } from '../workflow/type';
import type { StoreNodeItemType } from '../workflow/type/node';
import { PluginSourceEnum, PluginTypeEnum } from './constants';
import { MethodType } from './controller';
import { FlowNodeTemplateType } from '../workflow/type/node';
export type PluginItemSchema = {
_id: string;
@@ -24,16 +25,17 @@ export type PluginItemSchema = {
};
version?: 'v1' | 'v2';
nodeVersion?: string;
inited?: boolean;
};
/* plugin template */
export type PluginTemplateType = PluginRuntimeType & {
author?: string;
id: string;
source: `${PluginSourceEnum}`;
source: PluginSourceEnum;
templateType: FlowNodeTemplateType['templateType'];
intro: string;
nodeVersion: string;
version: string;
};
export type PluginRuntimeType = {

View File

@@ -4,7 +4,7 @@ import { NodeInputKeyEnum } from './constants';
export type SelectedDatasetType = { datasetId: string }[];
export type HttpBodyType<T = Record<string, any>> = {
[NodeInputKeyEnum.addInputParam]: Record<string, any>;
// [NodeInputKeyEnum.addInputParam]: Record<string, any>;
} & T;
export type HttpQueryType = {
appId: string;

View File

@@ -1,13 +1,15 @@
export enum FlowNodeTemplateTypeEnum {
systemInput = 'systemInput',
ai = 'ai',
function = 'function',
tools = 'tools',
textAnswer = 'textAnswer',
functionCall = 'functionCall',
externalCall = 'externalCall',
personalPlugin = 'personalPlugin',
search = 'search',
multimodal = 'multimodal',
communication = 'communication',
other = 'other'
other = 'other',
teamApp = 'teamApp'
}
export enum WorkflowIOValueTypeEnum {
@@ -84,6 +86,9 @@ export enum NodeInputKeyEnum {
datasetSearchExtensionModel = 'datasetSearchExtensionModel',
datasetSearchExtensionBg = 'datasetSearchExtensionBg',
// concat dataset
datasetQuoteList = 'system_datasetQuoteList',
// context extract
contextExtractInput = 'content',
extractKeys = 'extractKeys',
@@ -180,8 +185,6 @@ export const variableMap = {
}
};
export const DYNAMIC_INPUT_REFERENCE_KEY = 'DYNAMIC_INPUT_REFERENCE_KEY';
/* run time */
export enum RuntimeEdgeStatusEnum {
'waiting' = 'waiting',
@@ -190,3 +193,4 @@ export enum RuntimeEdgeStatusEnum {
}
export const VARIABLE_NODE_ID = 'VARIABLE_NODE_ID';
export const DYNAMIC_INPUT_REFERENCE_KEY = 'DYNAMIC_INPUT_REFERENCE_KEY';

View File

@@ -1,8 +1,11 @@
import { WorkflowIOValueTypeEnum } from '../constants';
export enum FlowNodeInputTypeEnum { // render ui
reference = 'reference', // reference to other node output
input = 'input', // one line input
numberInput = 'numberInput',
switch = 'switch', // true/false
select = 'select',
// editor
textarea = 'textarea',
@@ -22,8 +25,6 @@ export enum FlowNodeInputTypeEnum { // render ui
selectDatasetParamsModal = 'selectDatasetParamsModal',
settingDatasetQuotePrompt = 'settingDatasetQuotePrompt',
select = 'select',
hidden = 'hidden',
custom = 'custom'
}
@@ -114,7 +115,97 @@ export enum FlowNodeTypeEnum {
lafModule = 'lafModule',
ifElseNode = 'ifElseNode',
variableUpdate = 'variableUpdate',
code = 'code'
code = 'code',
textEditor = 'textEditor',
customFeedback = 'customFeedback'
}
// node IO value type
export const FlowValueTypeMap = {
[WorkflowIOValueTypeEnum.string]: {
label: 'string',
value: WorkflowIOValueTypeEnum.string,
description: ''
},
[WorkflowIOValueTypeEnum.number]: {
label: 'number',
value: WorkflowIOValueTypeEnum.number,
description: ''
},
[WorkflowIOValueTypeEnum.boolean]: {
label: 'boolean',
value: WorkflowIOValueTypeEnum.boolean,
description: ''
},
[WorkflowIOValueTypeEnum.object]: {
label: 'object',
value: WorkflowIOValueTypeEnum.object,
description: ''
},
[WorkflowIOValueTypeEnum.arrayString]: {
label: 'array<string>',
value: WorkflowIOValueTypeEnum.arrayString,
description: ''
},
[WorkflowIOValueTypeEnum.arrayNumber]: {
label: 'array<number>',
value: WorkflowIOValueTypeEnum.arrayNumber,
description: ''
},
[WorkflowIOValueTypeEnum.arrayBoolean]: {
label: 'array<boolean>',
value: WorkflowIOValueTypeEnum.arrayBoolean,
description: ''
},
[WorkflowIOValueTypeEnum.arrayObject]: {
label: 'array<object>',
value: WorkflowIOValueTypeEnum.arrayObject,
description: ''
},
[WorkflowIOValueTypeEnum.any]: {
label: 'any',
value: WorkflowIOValueTypeEnum.any,
description: ''
},
[WorkflowIOValueTypeEnum.chatHistory]: {
label: '历史记录',
value: WorkflowIOValueTypeEnum.chatHistory,
description: `{
obj: System | Human | AI;
value: string;
}[]`
},
[WorkflowIOValueTypeEnum.datasetQuote]: {
label: '知识库引用',
value: WorkflowIOValueTypeEnum.datasetQuote,
description: `{
id: string;
datasetId: string;
collectionId: string;
sourceName: string;
sourceId?: string;
q: string;
a: string
}[]`
},
[WorkflowIOValueTypeEnum.selectApp]: {
label: '选择应用',
value: WorkflowIOValueTypeEnum.selectApp,
description: ''
},
[WorkflowIOValueTypeEnum.selectDataset]: {
label: '选择知识库',
value: WorkflowIOValueTypeEnum.selectDataset,
description: `{
datasetId: string;
}`
},
[WorkflowIOValueTypeEnum.dynamic]: {
label: '动态输入',
value: WorkflowIOValueTypeEnum.dynamic,
description: ''
}
};
export const EDGE_TYPE = 'default';
export const defaultNodeVersion = '481';

View File

@@ -0,0 +1,17 @@
import { FlowNodeInputItemType } from '../../type/io';
export const getInputComponentProps = (input: FlowNodeInputItemType) => {
return {
referencePlaceholder: input.referencePlaceholder,
placeholder: input.placeholder,
maxLength: input.maxLength,
list: input.list,
markList: input.markList,
step: input.step,
max: input.max,
min: input.min,
defaultValue: input.defaultValue,
llmModelType: input.llmModelType,
customInputConfig: input.customInputConfig
};
};

View File

@@ -1,39 +0,0 @@
/*
react flow type
*/
import { FlowNodeInputTypeEnum, FlowNodeOutputTypeEnum, FlowNodeTypeEnum } from './constant';
import { WorkflowIOValueTypeEnum, NodeInputKeyEnum, NodeOutputKeyEnum } from '../constants';
import { SelectedDatasetType } from '../api';
import { LLMModelTypeEnum } from '../../ai/constants';
/* --------------- edit field ------------------- */
export type EditInputFieldMapType = EditOutputFieldMapType & {
inputType?: boolean;
};
export type EditOutputFieldMapType = {
key?: boolean;
description?: boolean;
valueType?: boolean; // output
required?: boolean;
defaultValue?: boolean;
};
export type EditNodeFieldType = {
inputType?: FlowNodeInputTypeEnum; // input type
valueType?: WorkflowIOValueTypeEnum;
required?: boolean;
key?: string;
label?: string;
description?: string;
isToolInput?: boolean;
defaultValue?: string;
maxLength?: number;
max?: number;
min?: number;
editField?: EditInputFieldMapType;
dynamicParamDefaultValue?: {
inputType?: FlowNodeInputTypeEnum; // input type
valueType?: WorkflowIOValueTypeEnum;
required?: boolean;
};
};

View File

@@ -1,11 +1,56 @@
import { ChatNodeUsageType } from '../../../support/wallet/bill/type';
import { ChatItemValueItemType, ToolRunResponseItemType } from '../../chat/type';
import {
ChatItemType,
UserChatItemValueItemType,
ChatItemValueItemType,
ToolRunResponseItemType
} from '../../chat/type';
import { FlowNodeInputItemType, FlowNodeOutputItemType } from '../type/io.d';
import { StoreNodeItemType } from '../type';
import { StoreNodeItemType } from '../type/node';
import { DispatchNodeResponseKeyEnum } from './constants';
import { StoreEdgeItemType } from '../type/edge';
import { NodeInputKeyEnum } from '../constants';
import { ClassifyQuestionAgentItemType } from '../template/system/classifyQuestion/type';
import { NextApiResponse } from 'next';
import { UserModelSchema } from '../../../support/user/type';
import { AppDetailType, AppSchema } from '../../app/type';
import { RuntimeNodeItemType } from '../runtime/type';
import { RuntimeEdgeItemType } from './edge';
/* workflow props */
export type ChatDispatchProps = {
res?: NextApiResponse;
mode: 'test' | 'chat' | 'debug';
teamId: string;
tmbId: string;
user: UserModelSchema;
app: AppDetailType | AppSchema;
chatId?: string;
responseChatItemId?: string;
histories: ChatItemType[];
variables: Record<string, any>; // global variable
query: UserChatItemValueItemType[]; // trigger query
stream: boolean;
detail: boolean; // response detail
maxRunTimes: number;
isToolCall?: boolean;
};
export type ModuleDispatchProps<T> = ChatDispatchProps & {
node: RuntimeNodeItemType;
runtimeNodes: RuntimeNodeItemType[];
runtimeEdges: RuntimeEdgeItemType[];
params: T;
};
export type SystemVariablesType = {
appId: string;
chatId?: string;
responseChatItemId?: string;
histories: ChatItemType[];
};
/* node props */
export type RuntimeNodeItemType = {
nodeId: StoreNodeItemType['nodeId'];
name: StoreNodeItemType['name'];
@@ -21,6 +66,17 @@ export type RuntimeNodeItemType = {
pluginId?: string;
};
export type PluginRuntimeType = {
id: string;
teamId?: string;
name: string;
avatar: string;
showStatus?: boolean;
currentCost?: number;
nodes: StoreNodeItemType[];
edges: StoreEdgeItemType[];
};
export type RuntimeEdgeItemType = StoreEdgeItemType & {
status: 'waiting' | 'active' | 'skipped';
};
@@ -87,6 +143,9 @@ export type DispatchNodeResponseType = {
// code
codeLog?: string;
// plugin
pluginOutput?: Record<string, any>;
};
export type DispatchNodeResultType<T> = {

View File

@@ -1,7 +1,7 @@
import { ChatCompletionRequestMessageRoleEnum } from '../../ai/constants';
import { NodeInputKeyEnum, NodeOutputKeyEnum } from '../constants';
import { FlowNodeTypeEnum } from '../node/constant';
import { StoreNodeItemType } from '../type';
import { StoreNodeItemType } from '../type/node';
import { StoreEdgeItemType } from '../type/edge';
import { RuntimeEdgeItemType, RuntimeNodeItemType } from './type';
import { VARIABLE_NODE_ID } from '../constants';
@@ -123,6 +123,7 @@ export const checkNodeRunStatus = ({
(item) => item.target === node.nodeId
);
// Entry
if (workflowEdges.length === 0) {
return 'run';
}

View File

@@ -5,88 +5,66 @@ import { AiChatModule } from './system/aiChat';
import { DatasetSearchModule } from './system/datasetSearch';
import { DatasetConcatModule } from './system/datasetConcat';
import { AssignedAnswerModule } from './system/assignedAnswer';
import { ClassifyQuestionModule } from './system/classifyQuestion';
import { ContextExtractModule } from './system/contextExtract';
import { HttpModule468 } from './system/http468';
import { ClassifyQuestionModule } from './system/classifyQuestion/index';
import { ContextExtractModule } from './system/contextExtract/index';
import { HttpNode468 } from './system/http468';
import { ToolModule } from './system/tools';
import { StopToolNode } from './system/stopTool';
import { RunAppModule } from './system/runApp';
import { RunAppModule } from './system/runApp/index';
import { PluginInputModule } from './system/pluginInput';
import { PluginOutputModule } from './system/pluginOutput';
import { RunPluginModule } from './system/runPlugin';
import { AiQueryExtension } from './system/queryExtension';
import type { FlowNodeTemplateType } from '../type';
import type { FlowNodeTemplateType } from '../type/node';
import { LafModule } from './system/laf';
import { IfElseNode } from './system/ifElse/index';
import { VariableUpdateNode } from './system/variableUpdate';
import { CodeNode } from './system/sandbox';
import { TextEditorNode } from './system/textEditor';
import { CustomFeedbackNode } from './system/customFeedback';
/* app flow module templates */
export const appSystemModuleTemplates: FlowNodeTemplateType[] = [
SystemConfigNode,
WorkflowStart,
const systemNodes: FlowNodeTemplateType[] = [
AiChatModule,
TextEditorNode,
AssignedAnswerModule,
DatasetSearchModule,
DatasetConcatModule,
RunAppModule,
ToolModule,
StopToolNode,
ClassifyQuestionModule,
ContextExtractModule,
HttpModule468,
HttpNode468,
AiQueryExtension,
LafModule,
IfElseNode,
VariableUpdateNode,
CodeNode
CodeNode,
RunAppModule
];
/* app flow module templates */
export const appSystemModuleTemplates: FlowNodeTemplateType[] = [
SystemConfigNode,
WorkflowStart,
...systemNodes,
CustomFeedbackNode
];
/* plugin flow module templates */
export const pluginSystemModuleTemplates: FlowNodeTemplateType[] = [
PluginInputModule,
PluginOutputModule,
AiChatModule,
AssignedAnswerModule,
DatasetSearchModule,
DatasetConcatModule,
RunAppModule,
ToolModule,
StopToolNode,
ClassifyQuestionModule,
ContextExtractModule,
HttpModule468,
AiQueryExtension,
LafModule,
IfElseNode,
VariableUpdateNode,
CodeNode
...systemNodes
];
/* all module */
export const moduleTemplatesFlat: FlowNodeTemplateType[] = [
...appSystemModuleTemplates.concat(
pluginSystemModuleTemplates.filter(
(item) => !appSystemModuleTemplates.find((app) => app.id === item.id)
)
),
EmptyNode,
SystemConfigNode,
WorkflowStart,
AiChatModule,
DatasetSearchModule,
DatasetConcatModule,
AssignedAnswerModule,
ClassifyQuestionModule,
ContextExtractModule,
HttpModule468,
ToolModule,
StopToolNode,
AiChatModule,
RunAppModule,
PluginInputModule,
PluginOutputModule,
RunPluginModule,
AiQueryExtension,
LafModule,
IfElseNode,
VariableUpdateNode,
CodeNode
RunPluginModule
];

View File

@@ -9,9 +9,9 @@ export const Output_Template_AddOutput: FlowNodeOutputItemType = {
type: FlowNodeOutputTypeEnum.dynamic,
valueType: WorkflowIOValueTypeEnum.dynamic,
label: '',
editField: {
key: true,
valueType: true
customFieldConfig: {
selectValueTypeList: Object.values(WorkflowIOValueTypeEnum),
showDescription: false,
showDefaultValue: false
}
};

View File

@@ -3,7 +3,7 @@ import {
FlowNodeOutputTypeEnum,
FlowNodeTypeEnum
} from '../../node/constant';
import { FlowNodeTemplateType } from '../../type';
import { FlowNodeTemplateType } from '../../type/node';
import {
WorkflowIOValueTypeEnum,
NodeInputKeyEnum,
@@ -22,11 +22,11 @@ import { getHandleConfig } from '../utils';
export const AiChatModule: FlowNodeTemplateType = {
id: FlowNodeTypeEnum.chatNode,
templateType: FlowNodeTemplateTypeEnum.textAnswer,
templateType: FlowNodeTemplateTypeEnum.ai,
flowNodeType: FlowNodeTypeEnum.chatNode,
sourceHandle: getHandleConfig(true, true, true, true),
targetHandle: getHandleConfig(true, true, true, true),
avatar: '/imgs/workflow/AI.png',
avatar: 'core/workflow/template/aiChat',
name: 'AI 对话',
intro: 'AI 大模型对话',
showStatus: true,

View File

@@ -1,5 +1,5 @@
import { FlowNodeInputTypeEnum, FlowNodeTypeEnum } from '../../node/constant';
import { FlowNodeTemplateType } from '../../type/index.d';
import { FlowNodeTemplateType } from '../../type/node.d';
import {
WorkflowIOValueTypeEnum,
NodeInputKeyEnum,
@@ -9,11 +9,11 @@ import { getHandleConfig } from '../utils';
export const AssignedAnswerModule: FlowNodeTemplateType = {
id: FlowNodeTypeEnum.answerNode,
templateType: FlowNodeTemplateTypeEnum.textAnswer,
templateType: FlowNodeTemplateTypeEnum.tools,
flowNodeType: FlowNodeTypeEnum.answerNode,
sourceHandle: getHandleConfig(true, true, true, true),
targetHandle: getHandleConfig(true, true, true, true),
avatar: '/imgs/workflow/reply.png',
avatar: 'core/workflow/template/reply',
name: '指定回复',
intro:
'该模块可以直接回复一段指定的内容。常用于引导、提示。非字符串内容传入时,会转成字符串进行输出。',

View File

@@ -2,30 +2,30 @@ import {
FlowNodeInputTypeEnum,
FlowNodeOutputTypeEnum,
FlowNodeTypeEnum
} from '../../node/constant';
import { FlowNodeTemplateType } from '../../type';
} from '../../../node/constant';
import { FlowNodeTemplateType } from '../../../type/node';
import {
WorkflowIOValueTypeEnum,
NodeInputKeyEnum,
FlowNodeTemplateTypeEnum,
NodeOutputKeyEnum
} from '../../constants';
} from '../../../constants';
import {
Input_Template_SelectAIModel,
Input_Template_History,
Input_Template_UserChatInput
} from '../input';
import { Input_Template_System_Prompt } from '../input';
import { LLMModelTypeEnum } from '../../../ai/constants';
import { getHandleConfig } from '../utils';
} from '../../input';
import { Input_Template_System_Prompt } from '../../input';
import { LLMModelTypeEnum } from '../../../../ai/constants';
import { getHandleConfig } from '../../utils';
export const ClassifyQuestionModule: FlowNodeTemplateType = {
id: FlowNodeTypeEnum.classifyQuestion,
templateType: FlowNodeTemplateTypeEnum.functionCall,
templateType: FlowNodeTemplateTypeEnum.ai,
flowNodeType: FlowNodeTypeEnum.classifyQuestion,
sourceHandle: getHandleConfig(false, false, false, false),
targetHandle: getHandleConfig(true, false, true, true),
avatar: '/imgs/workflow/cq.png',
avatar: 'core/workflow/template/questionClassify',
name: '问题分类',
intro: `根据用户的历史记录和当前问题判断该次提问的类型。可以添加多组问题类型,下面是一个模板例子:\n类型1: 打招呼\n类型2: 关于商品“使用”问题\n类型3: 关于商品“购买”问题\n类型4: 其他问题`,
showStatus: true,

View File

@@ -0,0 +1,4 @@
export type ClassifyQuestionAgentItemType = {
value: string;
key: string;
};

View File

@@ -2,25 +2,25 @@ import {
FlowNodeInputTypeEnum,
FlowNodeOutputTypeEnum,
FlowNodeTypeEnum
} from '../../node/constant';
import { FlowNodeTemplateType } from '../../type';
} from '../../../node/constant';
import { FlowNodeTemplateType } from '../../../type/node';
import {
WorkflowIOValueTypeEnum,
NodeInputKeyEnum,
NodeOutputKeyEnum,
FlowNodeTemplateTypeEnum
} from '../../constants';
import { Input_Template_SelectAIModel, Input_Template_History } from '../input';
import { LLMModelTypeEnum } from '../../../ai/constants';
import { getHandleConfig } from '../utils';
} from '../../../constants';
import { Input_Template_SelectAIModel, Input_Template_History } from '../../input';
import { LLMModelTypeEnum } from '../../../../ai/constants';
import { getHandleConfig } from '../../utils';
export const ContextExtractModule: FlowNodeTemplateType = {
id: FlowNodeTypeEnum.contentExtract,
templateType: FlowNodeTemplateTypeEnum.functionCall,
templateType: FlowNodeTemplateTypeEnum.ai,
flowNodeType: FlowNodeTypeEnum.contentExtract,
sourceHandle: getHandleConfig(true, true, true, true),
targetHandle: getHandleConfig(true, true, true, true),
avatar: '/imgs/workflow/extract.png',
avatar: 'core/workflow/template/extractJson',
name: '文本内容提取',
intro: '可从文本中提取指定的数据例如sql语句、搜索关键词、代码等',
showStatus: true,

View File

@@ -0,0 +1,8 @@
export type ContextExtractAgentItemType = {
valueType: 'string' | 'number' | 'boolean';
desc: string;
key: string;
required: boolean;
defaultValue?: string;
enum?: string;
};

View File

@@ -0,0 +1,30 @@
import { FlowNodeInputTypeEnum, FlowNodeTypeEnum } from '../../node/constant';
import { FlowNodeTemplateType } from '../../type/node.d';
import {
WorkflowIOValueTypeEnum,
FlowNodeTemplateTypeEnum,
NodeInputKeyEnum
} from '../../constants';
import { getHandleConfig } from '../utils';
export const CustomFeedbackNode: FlowNodeTemplateType = {
id: FlowNodeTypeEnum.customFeedback,
templateType: FlowNodeTemplateTypeEnum.other,
flowNodeType: FlowNodeTypeEnum.customFeedback,
sourceHandle: getHandleConfig(true, true, true, true),
targetHandle: getHandleConfig(true, true, true, true),
avatar: 'core/workflow/template/customFeedback',
name: '自定义反馈',
intro: '该模块被触发时,会给当前的对话记录增加一条反馈。可用于自动记录对话效果等。',
version: '486',
inputs: [
{
key: NodeInputKeyEnum.textareaInput,
renderTypeList: [FlowNodeInputTypeEnum.textarea, FlowNodeInputTypeEnum.reference],
valueType: WorkflowIOValueTypeEnum.string,
required: true,
label: '反馈的文本'
}
],
outputs: []
};

View File

@@ -3,7 +3,7 @@ import {
FlowNodeOutputTypeEnum,
FlowNodeTypeEnum
} from '../../node/constant';
import { FlowNodeTemplateType } from '../../type';
import { FlowNodeTemplateType } from '../../type/node';
import {
WorkflowIOValueTypeEnum,
NodeInputKeyEnum,
@@ -27,8 +27,7 @@ export const getOneQuoteInputTemplate = ({
renderTypeList: [FlowNodeInputTypeEnum.reference],
label: `引用${index}`,
debugLabel: '知识库引用',
canEdit: key !== defaultQuoteKey,
description: '',
canEdit: true,
valueType: WorkflowIOValueTypeEnum.datasetQuote
});
@@ -38,11 +37,11 @@ export const DatasetConcatModule: FlowNodeTemplateType = {
templateType: FlowNodeTemplateTypeEnum.other,
sourceHandle: getHandleConfig(true, true, true, true),
targetHandle: getHandleConfig(true, true, true, true),
avatar: '/imgs/workflow/concat.svg',
avatar: 'core/workflow/template/datasetConcat',
name: '知识库搜索引用合并',
intro: '可以将多个知识库搜索结果进行合并输出。使用 RRF 的合并方式进行最终排序输出。',
showStatus: false,
version: '481',
version: '486',
inputs: [
{
key: NodeInputKeyEnum.datasetMaxTokens,
@@ -52,11 +51,11 @@ export const DatasetConcatModule: FlowNodeTemplateType = {
valueType: WorkflowIOValueTypeEnum.number
},
{
key: 'customComponent',
key: NodeInputKeyEnum.datasetQuoteList,
renderTypeList: [FlowNodeInputTypeEnum.custom],
label: ''
},
getOneQuoteInputTemplate({ key: defaultQuoteKey, index: 1 })
}
// getOneQuoteInputTemplate({ key: defaultQuoteKey, index: 1 })
],
outputs: [
{

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