Compare commits

..

323 Commits
v3.8.3 ... v4.2

Author SHA1 Message Date
Archer
9415e22de9 v4.2 (#217)
* fix: chat module link

* fix: url fetch check

* fix: import file ui

* feat: app logs

* perf: iframe icon

* imgs cdn

* perf: click range and pg
2023-08-24 21:08:49 +08:00
archer
2b50dac0e7 fix: imgs cdn 2023-08-24 09:23:17 +08:00
archer
e589350eb3 fix: base url 2023-08-24 09:20:46 +08:00
archer
a99ef9e2c0 docs 2023-08-24 09:06:25 +08:00
archer
34ab66bb69 fix: docs 2023-08-24 08:30:09 +08:00
archer
a5c8f34706 prompt 2023-08-23 18:53:46 +08:00
archer
e266ab6a2e docs 2023-08-23 18:47:32 +08:00
archer
7edc5c5b19 docs action 2023-08-23 18:27:48 +08:00
archer
f8fc53811c docs 2023-08-23 18:21:11 +08:00
archer
a3c4a856fa perf: default prompt 2023-08-23 16:20:53 +08:00
archer
6c70f0601d perf: vector unit 2023-08-23 15:09:27 +08:00
archer
6a39b51460 perf: plugin response 2023-08-23 15:09:26 +08:00
archer
a5f8fae3f2 perf: plus api 2023-08-23 15:09:26 +08:00
archer
7a231c6501 invite url 2023-08-23 15:09:25 +08:00
Carson Yang
c20fba11ba docs: update the framework of doc site (#207)
Signed-off-by: Carson Yang <yangchuansheng33@gmail.com>
2023-08-22 11:08:28 +08:00
archer
c7d0975f6d add bill range 2023-08-20 14:05:33 +08:00
archer
006b1be2c3 perf: quote prompt 2023-08-20 14:05:32 +08:00
archer
4d8c03ead5 docs 2023-08-19 22:02:27 +08:00
Archer
1fcdd7cb8d feat: url fetch and create file (#199)
* docs

* docs

* feat: url fetch and create file
2023-08-19 12:54:24 +08:00
archer
4054eb9d18 docs 2023-08-18 10:45:48 +08:00
archer
b8d339fe66 docs 2023-08-18 10:07:24 +08:00
archer
c5b5c440ca perf: url fetch 2023-08-17 23:54:47 +08:00
不做了睡大觉
59ccc8565b 页面抓取 (#185)
* Create GLM2对接教程.md

* 添加GLM2接入教程

* Delete GLM2对接教程.md

* Delete image.png

* Delete openai_api.py

* Delete openai_api_int4.py

* Delete openai_api_int8.py

* Create GLM2对接教程.md

* 添加ChatGLM2接口

* Delete openai_api_int4.py

* Delete openai_api_int8.py

* Update openai_api.py

* Update GLM2对接教程.md

* 页面抓取接口

* Update package.json

* Update fetchContent.ts

* Delete GLM2对接教程.md

* Delete openai_api.py

---------

Co-authored-by: Archer <545436317@qq.com>
2023-08-17 23:25:36 +08:00
Archer
40168c56ea perf: logger (#186)
* feat: finish response

* perf: logger

* docs

* perf: log

* docs
2023-08-17 23:19:19 +08:00
Archer
324e4a0e75 v4.1 (#183)
* chat item table

* perf: chat item save

* docs

* limit

* docs

* docs

* perf: node card

* docs

* docs
2023-08-17 16:57:22 +08:00
Carson Yang
ce61ac3fac Update README.md (#181)
Add the option for self-hosting
2023-08-17 14:50:16 +08:00
archer
c9f4bad707 fix: file 2023-08-16 18:48:38 +08:00
archer
0455bdeace google search docs 2023-08-16 18:44:21 +08:00
archer
38e4a41cfd google search docs 2023-08-16 18:42:39 +08:00
archer
2c174aa91c feat: copy settings config 2023-08-16 18:21:55 +08:00
archer
a149b3a2ce feat: http docs 2023-08-16 16:35:08 +08:00
archer
72a9307eb3 fix: chat data outsize 2023-08-16 16:14:37 +08:00
archer
2f81fbc42f perf: http node response 2023-08-16 11:18:35 +08:00
archer
e8ff91c455 modules 2023-08-15 22:04:41 +08:00
archer
d8cd2e9b45 remove log 2023-08-15 20:38:11 +08:00
archer
cc57a7e27e perf: response tag;feat: history quote 2023-08-15 09:55:00 +08:00
archer
b8a65e1742 whole response modal 2023-08-14 17:45:48 +08:00
archer
7261f2250c cursor 2023-08-14 12:10:22 +08:00
archer
bb7596c3d5 feat: queue len show 2023-08-14 11:39:42 +08:00
archer
4952a48c52 perf: unlock training 2023-08-14 10:48:03 +08:00
archer
90f5f84bd8 feat: del dat confirm 2023-08-14 10:43:05 +08:00
archer
3a49efd46d pg table name 2023-08-14 10:36:15 +08:00
archer
c5fd5706a1 svg logo 2023-08-14 10:29:52 +08:00
archer
d4d9e1fe65 fix: markdonw link 2023-08-14 10:21:20 +08:00
archer
0d7022026b fix: file selector 2023-08-14 10:15:57 +08:00
archer
36bd25822d licence 2023-08-11 22:03:29 +08:00
archer
716423109e read 2023-08-11 21:33:52 +08:00
Archer
a0c397cfd2 docs (#165)
* perf: log

* README

* docs
2023-08-10 14:26:10 +08:00
archer
4dc0fd3c3f fix: completions delta 2023-08-10 13:15:26 +08:00
archer
f70a988574 perf: docs 2023-08-10 13:11:39 +08:00
archer
63c832d883 perf: search prompt, upload step and psw len 2023-08-10 11:49:32 +08:00
archer
9ea19b8eaa docs 2023-08-10 10:30:35 +08:00
archer
85feb005b9 feat: data config set scripts 2023-08-10 09:37:23 +08:00
Archer
b7b222fdfb perf: env template (#163) 2023-08-09 20:41:44 +08:00
Archer
adabc14340 del file (#162) 2023-08-09 20:00:27 +08:00
Archer
657d0ad374 flow moduoles (#161)
* flow intro

* docs:flow modules

* docs:flow modules
2023-08-09 18:07:58 +08:00
Archer
b6f9f77ed4 chat model config (#158)
* chat model config

* fix: i18n next
2023-08-09 11:08:39 +08:00
Archer
da4b14fbf8 docs (#156)
* docs

* docs

* docs

* docs

* init docs
2023-08-08 21:15:33 +08:00
archer
3993f520c7 docs 2023-08-08 16:58:19 +08:00
archer
48ab2d6338 docs 2023-08-08 16:42:27 +08:00
archer
93a04cc174 docs 2023-08-08 16:32:50 +08:00
archer
eb897daef2 docs 2023-08-08 16:22:37 +08:00
archer
5116bf7d25 docs 2023-08-08 16:14:03 +08:00
archer
6531af6c3a docs icon 2023-08-08 13:44:20 +08:00
archer
d3aca33ba2 perf: git 2023-08-08 13:33:35 +08:00
archer
5fc9041d46 perf: git 2023-08-08 13:30:58 +08:00
archer
3cf38930eb homepage 2023-08-08 13:24:05 +08:00
archer
37fe67dc81 fix: gitlogin 2023-08-07 19:31:49 +08:00
archer
78906d8557 perf: sse 2023-08-07 18:04:50 +08:00
archer
b142c04b95 perf: git 2023-08-07 17:59:17 +08:00
archer
a4c1a04900 iframe 2023-08-07 17:54:35 +08:00
archer
a178de37de git 2023-08-07 17:32:27 +08:00
archer
251f2225ee perf: generateVector 2023-08-07 17:31:37 +08:00
archer
ce729dff1f feat: git login 2023-08-07 17:19:04 +08:00
archer
206eb81bb4 feat: copy module 2023-08-07 14:45:49 +08:00
archer
90406fce9e feat: default message 2023-08-07 13:48:53 +08:00
archer
89036f8aec perf: git star 2023-08-07 13:26:53 +08:00
archer
c26be2e885 perf: chat completion api 2023-08-07 13:18:45 +08:00
archer
2f614ac40d perf: app type 2023-08-07 12:59:52 +08:00
archer
e190ee92e8 perf: navbar 2023-08-07 11:23:39 +08:00
archer
b6e156db26 perf: chunk filter 2023-08-07 11:04:32 +08:00
archer
7fe20ef041 perf: chunk filter 2023-08-07 10:59:31 +08:00
archer
1964640d5c perf: pay 2023-08-07 09:32:01 +08:00
archer
09879004be fix: abort chat response 2023-08-05 14:14:51 +08:00
archer
236e7d3c3f content censor 2023-08-05 13:26:48 +08:00
archer
8d3ad943be perf: send code 2023-08-05 12:56:37 +08:00
archer
bb824ab35e perf: user openai 2023-08-05 12:26:26 +08:00
archer
37a6293f5e fix: config 2023-08-05 11:51:40 +08:00
archer
761ae74b0a perf: token 2023-08-05 11:32:43 +08:00
archer
eb5a252654 fix: csv select 2023-08-04 18:32:37 +08:00
archer
a19c8b9106 i18n 2023-08-04 18:26:54 +08:00
archer
9a31407a01 feat: chat status 2023-08-04 18:16:48 +08:00
zhujingyang
c7bfd773e3 feat: file drag and drop (#2)
* feat file drag and drop

Signed-off-by: jingyang <3161362058@qq.com>

* add file select i18n

Signed-off-by: jingyang <3161362058@qq.com>

* add i18n Interpolation

Signed-off-by: jingyang <3161362058@qq.com>

---------

Signed-off-by: jingyang <3161362058@qq.com>
2023-08-04 18:16:34 +08:00
archer
25dc45c398 perf: extract 2023-08-04 14:17:52 +08:00
archer
6f37d7b460 default config 2023-08-04 14:00:50 +08:00
archer
94a241bbb1 feat: modules 2023-08-04 10:39:39 +08:00
archer
eb28bfb27b perf: ts 2023-08-04 10:06:34 +08:00
archer
ffd4e194bf feat: http request 2023-08-03 15:43:06 +08:00
archer
952da2a06e feat: http modules 2023-08-03 11:09:57 +08:00
archer
b7934ecc27 perf: extract modules 2023-08-02 18:08:27 +08:00
archer
8862e353aa fix: extract modules 2023-08-02 16:33:31 +08:00
archer
bf1f958dcd fix: tip 2023-08-02 15:37:18 +08:00
archer
83d569df83 perf: auth event model 2023-08-02 14:56:48 +08:00
archer
58d94e1018 head ,csv template and limit content size 2023-08-02 14:52:27 +08:00
archer
ae95a8908e fix: savechat.feat: extract flow 2023-08-02 14:17:43 +08:00
archer
58153306c5 extract modules 2023-08-02 14:17:42 +08:00
jingyang
2f28f57d78 feat translation of the user module
Signed-off-by: jingyang <3161362058@qq.com>
2023-08-02 10:50:38 +08:00
archer
911c5c00ba docs 2023-07-30 22:34:10 +08:00
archer
bd137d7595 root user 2023-07-30 12:53:54 +08:00
archer
40200c7c71 root user 2023-07-30 12:53:32 +08:00
archer
502d8d8c73 detail ux 2023-07-30 12:45:15 +08:00
archer
5f5d439f55 fix: sse headers and extract module 2023-07-30 12:26:21 +08:00
archer
b472127d3b fix: admin 2023-07-29 11:01:18 +08:00
archer
53a082278b fix: admin 2023-07-29 10:53:42 +08:00
archer
1704cf31de fix: table and message 2023-07-29 10:41:39 +08:00
archer
950dffaedf docs 2023-07-28 21:10:49 +08:00
archer
f764d81cdd feat: iframe embed 2023-07-28 17:44:07 +08:00
archer
5d0c8fa462 perf: dynamic 2023-07-28 16:09:10 +08:00
archer
0a689b0ab8 fix: save chat and hook 2023-07-28 15:56:50 +08:00
archer
a77e3880f4 fix: flow type 2023-07-28 15:41:50 +08:00
archer
fb8635a951 feat: user openai account 2023-07-28 13:29:06 +08:00
archer
dfda5285bd feat: set openai account 2023-07-28 12:02:23 +08:00
archer
7a56680935 update password 2023-07-28 10:33:45 +08:00
archer
f65a72821b perf: share link 2023-07-28 09:38:50 +08:00
archer
36b234c4fd feat: flow data type check 2023-07-28 09:00:10 +08:00
archer
aebe789e9f perf: modal 2023-07-27 14:36:21 +08:00
archer
1c4d2e92cf fix: init data 2023-07-27 12:14:03 +08:00
archer
118e333600 perf: flow value type 2023-07-27 12:10:30 +08:00
archer
97c7984dd1 perf: init db and config 2023-07-27 09:33:56 +08:00
archer
aa7fb6a65c img path 2023-07-26 22:30:47 +08:00
archer
efd6448043 docs 2023-07-26 22:28:29 +08:00
archer
cd2fd77df1 docs 2023-07-26 22:07:00 +08:00
archer
8be1834cfb docs 2023-07-26 17:32:26 +08:00
archer
bf2310cc29 perf: chat source 2023-07-26 16:15:21 +08:00
archer
c06a9fb52b perf: modal 2023-07-26 16:01:21 +08:00
archer
ffdef41bf2 feat: phone slider 2023-07-26 11:59:12 +08:00
archer
248be38939 feat: chat ui 2023-07-26 11:01:25 +08:00
archer
2b993b926a fix: i18n change 2023-07-25 22:18:18 +08:00
archer
b367082d38 i18n 2023-07-25 21:53:26 +08:00
archer
c5f50b65c9 feat: i18n 2023-07-25 18:10:55 +08:00
archer
815770467a fix: ui 2023-07-25 16:18:46 +08:00
archer
67724f2fa6 fix: tag 2023-07-25 16:14:03 +08:00
archer
e5e720e87e feat: chat model show 2023-07-25 16:11:16 +08:00
archer
35718b1f26 perf: app edit 2023-07-25 15:48:59 +08:00
archer
c16e2b8dd6 perf: app detail 2023-07-25 13:25:37 +08:00
archer
3adb97b396 fix: sse render 2023-07-25 13:25:37 +08:00
archer
6fc6c99477 feat: context box 2023-07-25 13:25:17 +08:00
archer
6fd83e1e75 perf: tooltip 2023-07-25 13:25:06 +08:00
archer
ea35ad2144 perf: quote modal 2023-07-25 13:25:05 +08:00
archer
1ffe1be562 perf: response store 2023-07-25 13:25:04 +08:00
archer
ba965320d5 perf: openapi 2023-07-25 13:25:04 +08:00
archer
67e10d6f2c perf: completion chatId 2023-07-25 13:25:03 +08:00
archer
b7d18e38d1 perf: template 2023-07-25 13:25:03 +08:00
archer
5e0b147048 perf: form format modules 2023-07-25 13:25:02 +08:00
archer
6027a966d2 perf: completion dispatch 2023-07-25 13:25:01 +08:00
archer
8151350d9f fix: register 2023-07-25 13:25:01 +08:00
archer
323953462b perf: phone ui 2023-07-25 13:25:00 +08:00
archer
f5fad6083a fix: chat test overflow 2023-07-25 13:24:59 +08:00
archer
e49a831cc4 perf: response key 2023-07-25 13:24:59 +08:00
archer
fdcf53ea38 feat: overview setting 2023-07-25 13:24:58 +08:00
archer
b7b20a353f ts and app detail 2023-07-25 13:24:57 +08:00
archer
f362ba2589 perf: date and warning 2023-07-25 13:24:57 +08:00
archer
e0b6860706 user ui 2023-07-25 13:24:56 +08:00
archer
9fefaa8e18 perf: promotion 2023-07-25 13:24:55 +08:00
archer
6d358ef3e6 feat: admin add user 2023-07-25 13:24:54 +08:00
archer
82e7776a77 configmap 2023-07-25 13:24:54 +08:00
archer
75c8c42530 perf: qa 2023-07-25 13:24:53 +08:00
archer
62ee28b130 configmap 2023-07-25 13:24:52 +08:00
archer
c46a37541c perf: config fe 2023-07-25 13:24:52 +08:00
archer
47af8d1c3d perf: config fe 2023-07-25 13:24:50 +08:00
archer
7a76f54148 fix: bill, app detail 2023-07-25 13:24:28 +08:00
archer
58cbf10c85 init 2023-07-25 13:24:27 +08:00
archer
7fe2017ab6 fix: ui 2023-07-25 13:24:27 +08:00
archer
51b98df4cb perf: ui 2023-07-25 13:24:26 +08:00
archer
ba73762285 fix: modules 2023-07-25 13:24:25 +08:00
archer
a993eba7f0 ts 2023-07-25 13:24:23 +08:00
archer
2330186a09 perf: abort 2023-07-25 13:23:45 +08:00
archer
8a25aeabc4 perf: template 2023-07-25 13:23:45 +08:00
archer
a510f96b83 markdown guide 2023-07-25 13:23:44 +08:00
archer
505aff3dbf perf: ui 2023-07-25 13:23:40 +08:00
archer
f9d83c481f guide node 2023-07-25 13:23:05 +08:00
archer
d346d38677 perf: txt 2023-07-25 13:23:05 +08:00
archer
f71ce25c46 flow chat 2023-07-25 13:23:00 +08:00
archer
ecce182a20 code 2023-07-25 13:22:53 +08:00
archer
509ca92f0a fix: phone 2023-07-25 13:22:52 +08:00
archer
44e360b61b name 2023-07-25 13:22:50 +08:00
archer
dc1599ba3c name 2023-07-25 13:22:37 +08:00
archer
53a4d9db05 perf: quote response 2023-07-25 13:22:36 +08:00
archer
60a9dfb55f perf: bill 2023-07-25 13:22:35 +08:00
archer
f546068354 app template 2023-07-25 13:22:35 +08:00
archer
ed42bb6ce8 feat: charts 2023-07-25 13:22:34 +08:00
archer
246283ee1c kb 2023-07-25 13:22:32 +08:00
archer
98a5796592 ssr init 2023-07-25 13:22:09 +08:00
archer
877aab858b fix: phone ui 2023-07-25 13:22:09 +08:00
archer
077ee9504f app phone ui 2023-07-25 13:22:08 +08:00
archer
5a96e167ee feat: kb ui 2023-07-25 13:22:07 +08:00
archer
358c4716f9 feat: refresh max token 2023-07-25 13:22:07 +08:00
archer
f3715731c4 perf: bill 2023-07-25 13:22:04 +08:00
archer
726de0396b ui 2023-07-25 13:20:40 +08:00
archer
b4d46ff34d feat: app detail 2023-07-25 13:20:39 +08:00
archer
6c72c20317 variable name 2023-07-25 13:20:38 +08:00
archer
eb68b35ddf fix: save chat 2023-07-25 13:20:38 +08:00
archer
b2e2f60e0d chatbox ui 2023-07-25 13:20:35 +08:00
archer
eb768d9c04 chat box 2023-07-25 13:20:04 +08:00
archer
cd77d81135 feat: app ui 2023-07-25 13:20:03 +08:00
archer
aef42cef9d perf: attribute 2023-07-25 13:20:03 +08:00
archer
23642af6e2 feat: agent and ui 2023-07-25 13:20:02 +08:00
archer
46f20c7dc3 add app 2023-07-25 13:20:01 +08:00
archer
8e9816d648 app page 2023-07-25 13:20:01 +08:00
archer
6e1ef89d65 myapps 2023-07-25 13:20:00 +08:00
archer
9bdd5f522d feat: v4 2023-07-25 13:19:59 +08:00
archer
4c54e1821b feat: app module 2023-07-25 13:19:58 +08:00
stakeswky
7e6272ca1b 添加embedding接口 (#136) 2023-07-25 12:19:10 +08:00
allen
70306295eb 修正Content-type问题 (#135)
charset-utf-8应该为charset=utf-8,会导致部分三方优先判断Content-type错误null

Co-authored-by: liukai <liukai@quanwu.info>
2023-07-24 11:55:34 +08:00
archer
ac482eb9f9 git actions 2023-07-23 17:42:53 +08:00
archer
002d53108f perf: queue do not delete task 2023-07-23 17:42:53 +08:00
中弈
792e5bf7e4 Merge pull request #128 from labring/fanux-patch-1
Update README.md, suggest using sealos to deploy fastGPT
2023-07-14 16:40:28 +08:00
中弈
cf201267af Update README.md, suggest using sealos to deploy fastGPT 2023-07-14 16:40:15 +08:00
stakeswky
ea2b8b468c 添加ChatGLM2教程 (#126)
* Create GLM2对接教程.md

* 添加GLM2接入教程

* Delete GLM2对接教程.md

* Delete image.png

* Delete openai_api.py

* Delete openai_api_int4.py

* Delete openai_api_int8.py

* Create GLM2对接教程.md

* 添加ChatGLM2接口

* Delete openai_api_int4.py

* Delete openai_api_int8.py

* Update openai_api.py

* Update GLM2对接教程.md
2023-07-13 19:51:00 +08:00
stakeswky
0be7a3e355 添加ChatGLM2教程 (#125)
* Create GLM2对接教程.md

* 添加GLM2接入教程

* Delete GLM2对接教程.md

* Delete image.png

* Delete openai_api.py

* Delete openai_api_int4.py

* Delete openai_api_int8.py

* Create GLM2对接教程.md

* 添加ChatGLM2接口

* Delete openai_api_int4.py

* Delete openai_api_int8.py

* Update openai_api.py

* Update GLM2对接教程.md
2023-07-13 09:21:19 +08:00
mrhaoji
5f784e1def fix: deploy doc for macOS (#124)
missing 'source' field in pg init sql
and other optimization
2023-07-13 08:38:25 +08:00
moonrailgun
77dafe4337 chore: migrate c121914yu to labring (#121)
* chore: migrate c121914yu to labring

* style: delete unused files

About those files:
https://www.sulinehk.com/post/reasons-and-solutions-for-the-zone.identifier-file-appearing-in-wsl/
2023-07-13 08:38:10 +08:00
archer
22a5dea963 docs 2023-07-09 15:25:01 +08:00
archer
54542ba11d gpt4low gg 2023-07-07 14:08:06 +08:00
archer
f10e8775fb init.sql 2023-07-07 09:38:43 +08:00
archer
a04b661864 fix: kb un refresh 2023-07-06 10:49:51 +08:00
archer
569772148f model 2023-07-05 18:12:00 +08:00
archer
63d1657f9b admin withdraw 2023-07-05 11:25:12 +08:00
archer
d00ac152b5 price 2023-07-05 09:54:20 +08:00
archer
e979a55f19 fix: ts 2023-07-04 21:35:09 +08:00
archer
026d87c61e fix: refresh 2023-07-04 21:30:42 +08:00
archer
2a45fe520b perf: code and inform 2023-07-04 21:24:32 +08:00
archer
8635de866f docs 2023-07-04 18:09:09 +08:00
archer
982e36e79d docs 2023-07-04 15:54:18 +08:00
archer
dda7847f77 price 2023-07-04 11:52:32 +08:00
archer
93fc9ee65d perf: ci 2023-07-04 11:52:32 +08:00
archer
a4e2c6510f perf: admin 2023-07-04 11:52:31 +08:00
archer
c411ca4bd4 text 2023-07-04 11:52:31 +08:00
archer
8af10a7c9a perf: animation 2023-07-04 11:52:30 +08:00
archer
65cab349b0 fix: unstream response type 2023-07-04 11:52:29 +08:00
archer
ca814dcaf4 fix: admin chart 2023-07-04 11:52:29 +08:00
archer
1367ba9d32 feat: admin 2023-07-04 11:52:28 +08:00
archer
62489ef12f fix: share chat 2023-07-04 11:52:27 +08:00
archer
3d2043c16f docs 2023-07-04 11:52:27 +08:00
archer
95066262b7 close ssr query 2023-07-04 11:52:26 +08:00
archer
deb9be4160 fix: pay error catch 2023-07-04 11:52:26 +08:00
kssdxw
f382b2194d fix: openai data truncation (#112) 2023-07-04 11:51:56 +08:00
archer
a4744dd78f price 2023-06-25 20:38:49 +08:00
archer
a9d258d992 fix: docs 2023-06-25 16:30:13 +08:00
archer
f56a339ad1 perf: index 2023-06-25 16:05:43 +08:00
archer
68eca25df4 fix: ssr close 2023-06-25 14:16:54 +08:00
archer
9eed321471 perf: docker-compose 2023-06-25 13:41:44 +08:00
archer
426176db47 fix: apikey 2023-06-25 13:20:00 +08:00
archer
cfb31afbd9 fix: select ui;perf: max link and compose 2023-06-25 10:52:58 +08:00
archer
5be57da407 fix: v1 api 2023-06-24 21:39:34 +08:00
archer
057c3411b9 perf: fetch error 2023-06-24 21:21:53 +08:00
archer
83d755ad0e feat: limit prompt 2023-06-24 18:55:46 +08:00
JustSong
ec9852fc63 docs: update README (#103) 2023-06-24 00:38:08 +08:00
archer
4e6f8aefe8 docs 2023-06-23 23:40:07 +08:00
archer
11352b754a fix: model 2023-06-23 23:21:59 +08:00
archer
965ad34283 docs 2023-06-23 23:16:49 +08:00
archer
986206b691 perf: sse response 2023-06-23 23:11:22 +08:00
archer
6787f19d78 feat: price 2023-06-23 18:05:53 +08:00
archer
64c35eaa3a docs 2023-06-23 17:43:14 +08:00
archer
41ada6ecda perf: keys 2023-06-23 17:12:52 +08:00
archer
ae1f7a888e perf: token count;feat: chunk size 2023-06-23 15:08:30 +08:00
archer
9aace871ff fix: ssr 2023-06-21 18:04:36 +08:00
moonrailgun
39739f9305 chore: fix admin build problem (#101) 2023-06-21 15:40:51 +08:00
archer
ce757d918b fix: ssr 2023-06-21 15:22:07 +08:00
archer
d592d4e99a markdown 2023-06-21 15:22:06 +08:00
moonrailgun
11ce10cd80 feat: add zh translation and change title (#100) 2023-06-21 15:21:24 +08:00
archer
6fb312ccfd link text 2023-06-20 10:41:17 +08:00
archer
3166376173 fix: template 2023-06-20 10:40:49 +08:00
archer
a02a528737 perf: my models 2023-06-19 21:08:32 +08:00
archer
dd4ca27dc7 perf: deploy 2023-06-19 20:00:54 +08:00
archer
f2d37c30a5 feat: baidu statistic 2023-06-19 17:28:25 +08:00
archer
1d236f87ae perf: markdown redraw 2023-06-19 16:50:14 +08:00
archer
3b515c3c2d fix: choices empty 2023-06-19 11:30:26 +08:00
archer
e95f83ec8e docs 2023-06-18 23:52:40 +08:00
archer
03793c66da README 2023-06-18 23:25:16 +08:00
archer
84daf85393 fix: base url 2023-06-18 22:38:55 +08:00
archer
6c62d80a4c fix: refresh page 2023-06-18 22:19:49 +08:00
archer
ff2043c0fb feat: maxToken setting 2023-06-18 21:23:36 +08:00
archer
ee9afa310a feat: openapi v2 chat 2023-06-18 21:06:07 +08:00
archer
2b93ae2d00 fix: time conf 2023-06-17 21:53:04 +08:00
archer
00c93a63cd perf: queue link 2023-06-17 21:27:44 +08:00
archer
61447c60ac feat: new app page 2023-06-17 17:31:38 +08:00
archer
df2fda6176 feat: auth key 2023-06-16 00:26:11 +08:00
archer
bc2504832f fix: nextjs version 2023-06-16 00:03:52 +08:00
archer
33ffd9d7dd loading 2023-06-15 22:36:09 +08:00
archer
80578a08c8 perf: app store 2023-06-15 22:17:54 +08:00
archer
2463e11cb9 feat: date picker 2023-06-15 21:44:31 +08:00
archer
4cbe4ebdc3 perf: image 2023-06-15 20:06:56 +08:00
archer
bb36e637e0 perf: code 2023-06-15 17:32:35 +08:00
archer
6f9e929298 perf: code 2023-06-15 17:32:12 +08:00
archer
bf1592d2c6 feat: admin set share 2023-06-15 00:21:27 +08:00
archer
c6259fca78 perf: export source 2023-06-14 23:14:26 +08:00
archer
cf3eb3b7b5 perf: upload img 2023-06-14 22:45:47 +08:00
archer
7c52cec0ea perf: binary avatar 2023-06-14 22:26:11 +08:00
archer
7c159d8aba fix: markdown 2023-06-14 20:58:11 +08:00
archer
07f8e18c10 fix: gpt35 4k 2023-06-14 20:54:34 +08:00
archer
e4aeee7be3 perf: token count 2023-06-14 20:02:43 +08:00
archer
8036ed6143 perf: qa 2023-06-14 14:33:26 +08:00
archer
85e6a0f38d fix: token limit 2023-06-14 10:01:00 +08:00
archer
dab70378bb feat: gpt35-16k 2023-06-14 09:45:49 +08:00
archer
0a0febd2e6 perf: admin 2023-06-14 00:24:50 +08:00
archer
391332c8dd perf: ssr 2023-06-13 20:07:32 +08:00
archer
89e7c1abca perf: admin 2023-06-13 11:49:26 +08:00
archer
fc3c360985 fix: context menu 2023-06-13 10:52:44 +08:00
archer
006ba3b877 fix: mermaid 2023-06-12 23:17:48 +08:00
archer
5a534aa630 perf: del loading 2023-06-12 22:12:29 +08:00
archer
98e3c0a41f perf: mermaid overflow 2023-06-12 22:02:06 +08:00
archer
99e47849f5 perf: kb test 2023-06-12 21:59:30 +08:00
archer
ca4cd8af9d fix: sse 2023-06-12 20:55:37 +08:00
archer
36a0ea7e43 fix: sensitive check 2023-06-12 18:29:22 +08:00
archer
71dd7f3e6c feat: search test 2023-06-12 18:18:08 +08:00
archer
6ac7119edf feat: kb UI 2023-06-12 15:11:29 +08:00
archer
daf1148bb1 fix: package 2023-06-12 10:27:59 +08:00
archer
82b05b3d94 perf: share message 2023-06-12 10:24:12 +08:00
archer
9ab5cef516 fix: tag theme 2023-06-11 21:40:43 +08:00
archer
1ac3edccab perf: ui 2023-06-11 19:41:19 +08:00
archer
d3959a918c docs 2023-06-11 19:20:52 +08:00
archer
623018f408 perf: ui 2023-06-11 19:18:40 +08:00
667 changed files with 56200 additions and 20210 deletions

BIN
.github/imgs/intro1.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 548 KiB

BIN
.github/imgs/intro2.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 437 KiB

BIN
.github/imgs/intro3.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 574 KiB

BIN
.github/imgs/intro4.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 270 KiB

599
.github/imgs/logo.svg vendored Normal file
View File

@@ -0,0 +1,599 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="256px" height="256px" viewBox="0 0 256 256" enable-background="new 0 0 256 256" xml:space="preserve"> <image id="image0" width="256" height="256" x="0" y="0"
href="data:image/png;base64,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
MDqUEekAAAAASUVORK5CYII=" />
</svg>

After

Width:  |  Height:  |  Size: 45 KiB

71
.github/workflows/deploy-docs.yml vendored Normal file
View File

@@ -0,0 +1,71 @@
name: deploy-docs
on:
workflow_dispatch:
push:
paths:
- 'docSite/**'
branches:
- 'main'
tags:
- 'v*.*.*'
# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
# This workflow contains jobs "deploy-production"
deploy-production:
# The environment this job references
environment:
name: Production
url: ${{ steps.vercel-action.outputs.preview-url }}
# The type of runner that the job will run on
runs-on: ubuntu-22.04
# Job outputs
outputs:
docs: ${{ steps.filter.outputs.docs }}
# Steps represent a sequence of tasks that will be executed as part of the job
steps:
# Step 1 - Checks-out your repository under $GITHUB_WORKSPACE
- name: Checkout
uses: actions/checkout@v3
with:
submodules: recursive # Fetch submodules
fetch-depth: 0 # Fetch all history for .GitInfo and .Lastmod
# Step 2 Detect changes to Docs Content
- name: Detect changes in doc content
uses: dorny/paths-filter@v2
id: filter
with:
filters: |
docs:
- 'docSite/content/docs/**'
base: main
# Step 3 - Install Hugo (specific version)
- name: Install Hugo
uses: peaceiris/actions-hugo@v2
with:
hugo-version: '0.117.0'
extended: true
# Step 4 - Builds the site using Hugo
- name: Build
run: hugo -v --minify -s docSite
env:
HUGO_BASEURL: ${{ vars.BASE_URL }}
# Step 5 - Push our generated site to Vercel
- name: Deploy to Vercel
uses: amondnet/vercel-action@v25
id: vercel-action
with:
vercel-token: ${{ secrets.VERCEL_TOKEN }} # Required
vercel-org-id: ${{ secrets.VERCEL_ORG_ID }} #Required
vercel-project-id: ${{ secrets.VERCEL_PROJECT_ID }} #Required
github-comment: false
vercel-args: '--prod --local-config ../vercel.json' # Optional
working-directory: docSite/public

View File

@@ -1,13 +1,15 @@
name: Build images and copy image to docker
name: Build fastgpt images and copy image to docker hub
on:
workflow_dispatch:
push:
paths:
- 'client/**'
branches:
- 'main'
tags:
- 'v*.*.*'
jobs:
build-images:
build-fastgpt-images:
runs-on: ubuntu-20.04
steps:
- name: Checkout
@@ -52,7 +54,7 @@ jobs:
-f Dockerfile \
.
push-to-docker-hub:
needs: build-images
needs: build-fastgpt-images
runs-on: ubuntu-20.04
steps:
- name: Checkout code

7
.gitignore vendored
View File

@@ -5,6 +5,7 @@ node_modules/
out/
# production
build/
.astro/
# misc
.DS_Store
@@ -28,4 +29,8 @@ next-env.d.ts
platform.json
testApi/
local/
dist/
dist/
# hugo
**/.hugo_build.lock
docSite/public/

15
.vscode/settings.json vendored
View File

@@ -1,6 +1,15 @@
{
"editor.formatOnSave": true, //每次保存自动格式化
"editor.formatOnSave": true,
"editor.mouseWheelZoom": true,
"typescript.tsdk": "./client/node_modules/typescript/lib",
"prettier.prettierPath": "./node_modules/prettier"
"typescript.tsdk": "client/node_modules/typescript/lib",
"prettier.prettierPath": "./node_modules/prettier",
"i18n-ally.localesPaths": [
"client/public/locales"
],
"i18n-ally.enabledParsers": ["json"],
"i18n-ally.keystyle": "nested",
"i18n-ally.sortKeys": true,
"i18n-ally.keepFulfilled": true,
"i18n-ally.sourceLanguage": "zh", // 根据此语言文件翻译其他语言文件的变量和内容
"i18n-ally.displayLanguage": "en", // 显示语言
}

210
LICENSE
View File

@@ -1,201 +1,35 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
# FastGPT Open Source License
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
The FastGPT is licensed under the Apache License 2.0, with the following additional conditions:
1. Definitions.
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:
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
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.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
Please contact yujinlong@sealos.io by email to inquire about licensing matters.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
2. As a contributor, you should agree that your contributed code:
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
a. The producer can adjust the open-source agreement to be more strict or relaxed.
b. Can be used for commercial purposes, such as FastGPT's cloud business.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
Apart from this, all other rights and restrictions follow the Apache License 2.0. If you need more detailed information, you can refer to the full version of Apache License 2.0.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
The interactive design of this product is protected by appearance patent.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
© 2023 Sealos.
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
---
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
http://www.apache.org/licenses/LICENSE-2.0
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

120
README.md
View File

@@ -1,47 +1,121 @@
# Fast GPT
<div align="center">
Fast GPT 允许你使用自己的 openai API KEY 来快速的调用 openai 接口,目前集成了 Gpt35, Gpt4 和 embedding. 可构建自己的知识库。
<a href="https://fastgpt.run/"><img src="/.github/imgs/logo.svg" width="120" height="120" alt="fastgpt logo"></a>
# FastGPT
FastGPT 是一个基于 LLM 大语言模型的知识库问答系统,提供开箱即用的数据处理、模型调用等能力。同时可以通过 Flow 可视化进行工作流编排,从而实现复杂的问答场景!
</div>
<p align="center">
<a href="https://fastgpt.run/">线上体验</a>
·
<a href="https://doc.fastgpt.run/docs/intro">相关文档</a>
·
<a href="https://doc.fastgpt.run/docs/development">本地开发</a>
·
<a href="https://github.com/labring/FastGPT#-%E7%9B%B8%E5%85%B3%E9%A1%B9%E7%9B%AE">相关项目</a>
</p>
## 🛸 在线体验
🎉 [fastgpt.run](https://fastgpt.run/)
🎉 [ai.fastgpt.run](https://ai.fastgpt.run/)
[fastgpt.run](https://fastgpt.run/)(服务器在新加坡,部分地区可能无法直连)
![Demo](docs/imgs/demo.png?raw=true 'demo')
| | |
| ---------------------------------- | ---------------------------------- |
| ![Demo](./.github/imgs/intro1.png) | ![Demo](./.github/imgs/intro2.png) |
| ![Demo](./.github/imgs/intro3.png) | ![Demo](./.github/imgs/intro4.png) |
#### 知识库原理图
## 💡 功能
![KBProcess](docs/imgs/KBProcess.jpg?raw=true 'KBProcess')
1. 强大的可视化编排,轻松构建 AI 应用
- [x] 提供简易模式,无需操作编排
- [x] 用户对话前引导
- [x] 全局变量
- [x] 知识库搜索
- [x] 多 LLM 模型对话
- [x] 文本内容提取成结构化数据
- [x] HTTP 扩展
- [ ] 沙盒 JS 运行模块
- [ ] 连续对话引导
- [ ] 对话多路线选择
- [ ] 源文件引用追踪
2. 丰富的知识库预处理
- [x] 多库复用,混用
- [x] chunk 记录修改和删除
- [x] 支持直接分段导入
- [x] 支持 QA 拆分导入
- [x] 支持手动输入内容
- [x] 支持 url 读取导入
- [x] 支持 CSV 批量导入问答对
- [ ] 支持知识库单独设置向量模型
- [ ] 源文件存储
3. 多种效果测试渠道
- [x] 知识库单点搜索测试
- [x] 对话时反馈引用并可修改与删除
- [x] 完整上下文呈现
- [ ] 完整模块中间值呈现
4. OpenAPI
- [x] completions 接口(对齐 GPT 接口)
- [ ] 知识库 CRUD
5. 运营功能
- [x] 免登录分享窗口
- [x] Iframe 一键嵌入
- [ ] 统一查阅对话记录
## 👨‍💻 开发
项目技术栈: NextJs + TS + ChakraUI + Mongo + PostgresVector 插件)
这是一个平台项目,非单机项目,除了模型调用外还涉及非常多用户的内容。
[本地开发 Quick Start](docs/dev/README.md)
项目技术栈: NextJs + TS + ChakraUI + Mongo + PostgresVector 插件)
## 🚀 私有化部署
- **⚡ 快速部署**
- [Sealos 部署](https://sealos.io/docs/examples/ai-applications/install-fastgpt-on-desktop) 无需服务器,代理和域名。
- [docker-compose 部署](docs/deploy/docker.md)
- [由社区贡献的宝塔部署和本地运行教程](https://space.bilibili.com/431177525/channel/collectiondetail?sid=1370663)
> Sealos 的服务器在国外,不需要额外处理网络问题,无需服务器、无需魔法、无需域名,支持高并发 & 动态伸缩。点击以下按钮即可一键部署 👇
## :point_right: RoadMap
[![](https://cdn.jsdelivr.us/gh/labring-actions/templates@main/Deploy-on-Sealos.svg)](https://cloud.sealos.io/?openapp=system-fastdeploy%3FtemplateName%3Dfastgpt)
- [FastGpt RoadMap](https://kjqvjse66l.feishu.cn/docx/RVUxdqE2WolDYyxEKATcM0XXnte)
由于需要部署数据库,部署完后需要等待 2~4 分钟才能正常访问。默认用了最低配置,首次访问时会有些慢。
## 🏘️ 交流群
* [快开始本地开发](https://doc.fastgpt.run/docs/development)
* [部署 FastGPT](https://doc.fastgpt.run/docs/installation)
* [系统配置文件说明](https://doc.fastgpt.run/docs/installation/reference)
* [多模型配置](https://doc.fastgpt.run/docs/installation/reference/models)
* [版本升级](https://doc.fastgpt.run/docs/installation/upgrading)
* [API 文档](https://kjqvjse66l.feishu.cn/docx/DmLedTWtUoNGX8xui9ocdUEjnNh?pre_pathname=%2Fdrive%2Fhome%2F)
添加 wx 进入:
![Demo](https://otnvvf-imgs.oss.laf.run/wx300.jpg)
## 🏘️ 社区交流群
| 交流群 | 小助手 |
| --------------------------------------------------- | ---------------------------------------------- |
| ![](https://otnvvf-imgs.oss.laf.run/wxqun300-2.jpg) | ![](https://otnvvf-imgs.oss.laf.run/wx300.jpg) |
## 👀 其他
- [FastGpt 常见问题](https://kjqvjse66l.feishu.cn/docx/HtrgdT0pkonP4kxGx8qcu6XDnGh)
- [公众号接入](https://www.bilibili.com/video/BV1xh4y1t7fy/)
- [FastGpt + Laf 最佳实践,将知识库装入公众号,点击去 Laf 公众号体验效果](https://b4jky7-fastgpt.oss.laf.run/lafercode.png)
- [FastGpt V3.4 更新集合](https://www.bilibili.com/video/BV1Lo4y147Qh/?vd_source=92041a1a395f852f9d89158eaa3f61b4)
- [docker 部署教程视频](https://www.bilibili.com/video/BV1jo4y147fT/)
- [公众号接入视频教程](https://www.bilibili.com/video/BV1xh4y1t7fy/)
- [FastGpt 知识库演示](https://www.bilibili.com/video/BV1Wo4y1p7i1/)
## 💪 相关项目
- [Laf: 3 分钟快速接入三方应用](https://github.com/labring/laf)
- [Sealos: 快速部署集群应用](https://github.com/labring/sealos)
- [One API: 多模型管理,支持 Azure、文心一言等](https://github.com/songquanpeng/one-api)
- [TuShan: 5 分钟搭建后台管理系统](https://github.com/msgbyte/tushan)
## 🤝 第三方生态
- [luolinAI: 企微机器人,开箱即用](https://github.com/luolin-ai/FastGPT-Enterprise-WeChatbot)
## 🌟 Star History
[![Star History Chart](https://api.star-history.com/svg?repos=c121914yu/FastGPT&type=Date)](https://star-history.com/#c121914yu/FastGPT&Date)
[![Star History Chart](https://api.star-history.com/svg?repos=labring/FastGPT&type=Date)](https://star-history.com/#labring/FastGPT&Date)
## 使用协议
本仓库遵循 [FstGPT Open Source License](./LICENSE) 开源协议。
1. 允许作为后台服务直接商用,但不允许直接使用 saas 服务商用。
2. 需保留相关版权信息。
3. 完整请查看 [FstGPT Open Source License](./LICENSE)
4. 联系方式yujinlong@sealos.io, [点击查看定价策略](https://fael3z0zfze.feishu.cn/docx/F155dbirfo8vDDx2WgWc6extnwf)

115
README_en.md Normal file
View File

@@ -0,0 +1,115 @@
<div align="center">
<a href="https://fastgpt.run/"><img src="/.github/imgs/logo.svg" width="120" height="120" alt="fastgpt logo"></a>
# FastGPT
FastGPT is a knowledge-based question answering system based on the LLM language model, providing out-of-the-box capabilities for data processing, model invocation, and more. It also allows for complex question answering scenarios through visual workflow orchestration using Flow!
</div>
<p align="center">
<a href="https://fastgpt.run/">Online</a>
·
<a href="https://doc.fastgpt.run/docs/intro">Document</a>
·
<a href="https://doc.fastgpt.run/docs/development">Development</a>
·
<a href="https://doc.fastgpt.run/docs/installation">Deploy</a>
·
<a href="#powered-by">Power By</a>
</p>
## 🛸 Online
[fastgpt.run](https://fastgpt.run/)
| | |
| ---------------------------------- | ---------------------------------- |
| ![Demo](./.github/imgs/intro1.png) | ![Demo](./.github/imgs/intro2.png) |
| ![Demo](./.github/imgs/intro3.png) | ![Demo](./.github/imgs/intro4.png) |
## 💡 Features
1. Powerful visual orchestration for easy AI application building
- [x] Provides a simple mode without the need for orchestration operations
- [x] User dialogue pre-guidance
- [x] Global variables
- [x] Knowledge base search
- [x] Multi-LLM model dialogue
- [x] Extraction of text content into structured data
- [x] HTTP extension
- [ ] Sandbox JS runtime module
- [ ] Continuous dialogue guidance
- [ ] Dialogue multi-path selection
- [ ] Source file reference tracking
2. Rich knowledge base preprocessing
- [x] Multiple library reuse and mixing
- [x] Chunk record modification and deletion
- [x] Supports direct segment import
- [x] Supports QA split import
- [x] Supports manual input content
- [ ] Supports URL import reading
- [x] Supports batch import of Q&A pairs in CSV format
- [ ] Supports separate vector model settings for knowledge bases
- [ ] Source file storage
3. Multiple effect testing channels
- [x] Knowledge base single point search testing
- [x] Feedback references and ability to modify and delete during dialogue
- [x] Complete context presentation
- [ ] Complete module intermediate value presentation
4. OpenAPI
- [x] completions interface (aligned with GPT interface)
- [ ] Knowledge base CRUD
5. Operational functions
- [x] Login-free sharing window
- [x] One-click embedding with Iframe
- [ ] Unified access to dialogue records
## 👨‍💻 Development
Project tech stack: NextJs + TS + ChakraUI + Mongo + Postgres (Vector plugin)
- [Getting Started with Local Development](https://doc.fastgpt.run/docs/development)
- [Deploying FastGPT](https://doc.fastgpt.run/docs/installation)
- [System Configuration File Explanation](https://doc.fastgpt.run/docs/installation/reference)
- [Multi-model Configuration](https://doc.fastgpt.run/docs/installation/reference/models)
- [V3 Upgrade V4 Initialization](https://doc.fastgpt.run/docs/installation/upgrading)
<!-- ## :point_right: RoadMap
- [FastGpt RoadMap](https://kjqvjse66l.feishu.cn/docx/RVUxdqE2WolDYyxEKATcM0XXnte) -->
<!-- ## 🏘️ Community
| Community Group | Assistant |
| ------------------------------------------------- | ---------------------------------------------- |
| ![](https://otnvvf-imgs.oss.laf.run/wxqun300.jpg) | ![](https://otnvvf-imgs.oss.laf.run/wx300.jpg) | -->
## 👀 Others
- [FastGpt FAQ](https://kjqvjse66l.feishu.cn/docx/HtrgdT0pkonP4kxGx8qcu6XDnGh)
- [Docker Deployment Tutorial Video](https://www.bilibili.com/video/BV1jo4y147fT/)
- [Official Account Integration Video Tutorial](https://www.bilibili.com/video/BV1xh4y1t7fy/)
- [FastGpt Knowledge Base Demo](https://www.bilibili.com/video/BV1Wo4y1p7i1/)
## 💪 Related Projects
- [Laf: 3-minute quick access to third-party applications](https://github.com/labring/laf)
- [Sealos: Rapid deployment of cluster applications](https://github.com/labring/sealos)
- [One API: Multi-model management, supports Azure, Wenxin Yiyuan, etc.](https://github.com/songquanpeng/one-api)
- [TuShan: Build a backend management system in 5 minutes](https://github.com/msgbyte/tushan)
## 🤝 Third-party Ecosystem
- [luolinAI: Enterprise WeChat bot, ready to use](https://github.com/luolin-ai/FastGPT-Enterprise-WeChatbot)
## 🌟 Star History
[![Star History Chart](https://api.star-history.com/svg?repos=labring/FastGPT&type=Date)](https://star-history.com/#labring/FastGPT&Date)

View File

@@ -1,11 +0,0 @@
Dockerfile
.dockerignore
node_modules
npm-debug.log
README.md
.git
.yalc/
yalc.lock
testApi/
node_modules

View File

@@ -1,8 +0,0 @@
MONGODB_URI=mongodb://username:psw@0.0.0.0:27017/?authSource=admin
MONGODB_NAME=fastgpt
ADMIN_USER=username
ADMIN_PASS=password
ADMIN_SECRET=any
PARENT_URL=http://localhost:3000 # FastGpt服务的地址
PARENT_ROOT_KEY=rootkey # FastGpt 的rootkey
VITE_PUBLIC_SERVER_URL=http://localhost:3001 # 和server.js一致

1
admin/.gitignore vendored
View File

@@ -1 +0,0 @@
node_modules/

View File

@@ -1,48 +0,0 @@
# Install dependencies only when needed
FROM node:current-alpine AS builder
RUN npm config set registry https://registry.npmmirror.com/
RUN apk add --no-cache libc6-compat && npm install -g pnpm
RUN pnpm config set registry https://registry.npmmirror.com/
WORKDIR /app
ENV NEXT_TELEMETRY_DISABLED 1
ENV VITE_PUBLIC_SERVER_URL ''
# Install dependencies based on the preferred package manager
COPY . .
RUN \
[ -f pnpm-lock.yaml ] && pnpm install || \
(echo "Lockfile not found." && exit 1)
RUN pnpm build
# Production image, copy all the files and run next
FROM node:current-alpine AS runner
WORKDIR /app
ENV NODE_ENV production
ENV NEXT_TELEMETRY_DISABLED 1
RUN addgroup --system --gid 1001 nodejs
RUN adduser --system --uid 1001 nextjs
RUN sed -i 's/https/http/' /etc/apk/repositories
RUN apk add curl \
&& apk add ca-certificates \
&& update-ca-certificates
COPY package.json pnpm-lock.yaml* ./
COPY --from=builder /app/server.js ./server.js
COPY --from=builder /app/service ./service
COPY --from=builder /app/dist ./dist
RUN npm config set registry https://registry.npmmirror.com/
RUN npm install -g pnpm
RUN pnpm config set registry https://registry.npmmirror.com/
RUN pnpm install --prod
RUN npm remove -g pnpm
ENV PORT=3001
EXPOSE 3001
CMD ["node", "server.js"]

View File

@@ -1,201 +0,0 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View File

@@ -1,41 +0,0 @@
# FastGpt Admin
## 项目原理
使用 tushan 项目做前端,然后构造了一个与 mongodb 做沟通的 API 做后端,可以做到创建、修改和删除用户
## 开发
1. 复制 .env.template 文件,添加环境变量
2. pnpm i
3. pnpm dev
## 部署
1. 本地打包
`docker build -t registry.cn-hangzhou.aliyuncs.com/fastgpt/fastgpt-admin:latest . --network host --build-arg HTTP_PROXY=http://127.0.0.1:7890 --build-arg HTTPS_PROXY=http://127.0.0.1:7890`
2. 直接拉镜像: `registry.cn-hangzhou.aliyuncs.com/fastgpt/fastgpt-admin:latest`
3. 部署时候填写环境变量: 数据库同 FastGpt 一致
```
MONGODB_URI=mongodb://username:psw@0.0.0.0:27017/?authSource=admin
MONGODB_NAME=fastgpt
ADMIN_USER=username
ADMIN_PASS=password
ADMIN_SECRET=any
VITE_PUBLIC_SERVER_URL=http://localhost:3001 # 和server.js一致
```
## sealos 部署
1. 进入 sealos 官网: https://cloud.sealos.io/
2. 打开 App Launchpad(应用管理) 工具
3. 新建应用
1. 镜像名: registry.cn-hangzhou.aliyuncs.com/fastgpt/fastgpt-admin:latest
2. 容器端口: 3001
3. 环境变量: 参考上面
4. 打开外网访问开关
4. 点击部署。 完成后大约等待 1 分钟,
5. 点击 sealos 提供的外网访问地址,可以直接访问。

View File

@@ -1,13 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/logo.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Tushan</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.tsx"></script>
</body>
</html>

View File

@@ -1,41 +0,0 @@
{
"name": "kbgpt-deafult",
"private": true,
"version": "0.0.0",
"type": "module",
"author": "anonymous",
"scripts": {
"dev": "concurrently \"vite\" \"npm run start:api\"",
"build": "tsc && vite build",
"preview": "vite preview",
"start:api": "nodemon server.js"
},
"dependencies": {
"@arco-design/web-react": "^2.49.1",
"concurrently": "^8.1.0",
"cors": "^2.8.5",
"crypto": "^1.0.1",
"dayjs": "^1.11.8",
"dotenv": "^16.1.4",
"express": "^4.18.2",
"jsonwebtoken": "^9.0.0",
"mongoose": "^7.2.2",
"react": "^18.2.0",
"react-admin": "^4.11.0",
"react-dom": "^18.2.0",
"react-i18next": "^12.3.1",
"tushan": "^0.2.22"
},
"devDependencies": {
"@types/jsonexport": "^3.0.2",
"@types/lodash-es": "^4.17.7",
"@types/node": "^20.2.5",
"@types/react": "^18.0.28",
"@types/react-dom": "^18.0.11",
"@types/react-helmet": "^6.1.6",
"@types/styled-components": "^5.1.26",
"@vitejs/plugin-react": "^3.1.0",
"typescript": "^4.9.2",
"vite": "^4.2.1"
}
}

5472
admin/pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,10 +0,0 @@
<svg width="512" height="512" viewBox="0 0 512 512" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M28 88L49.5 57L118.5 29.5L248 51L323.5 122.5L360.5 324L301 421.5L164.5 412.5L118.5 324L127.5 225.5L143.5 184.5L151.5 130.5L127.5 95L82.5 80L49.5 95L28 88Z" fill="#DFDFDF"/>
<path d="M144.734 22.04C139.186 22.0047 133.638 22.1568 128.1 22.496C84.33 25.196 40.5 49 24.238 67.492C7.97598 85.984 4 91.601 4 91.601C4 91.601 34.922 98.392 57 97.5C79.078 96.608 111.355 88.82 127.692 104.564C144.032 120.309 151.428 146.017 135.232 175.709C116.062 210.852 102.516 271.862 115.086 332.235C127.656 392.609 168.054 451.995 254.814 478.007C288.29 488.043 333.639 494.757 376.459 485.673C420.966 476.885 472.309 450.915 483.351 422.563C474.101 431.448 463.911 437.703 453.149 442.353C471.455 421.433 484.884 392.621 489.939 354.179L492.469 334.939L476.147 345.435C465.644 352.19 455.562 358.838 446.054 363.831C448.692 357.959 451.092 350.611 453.784 341.054C442.687 356.244 430.054 366.409 415.186 372.526C405.952 372.023 396.833 367.659 385.976 356.429C374.618 344.682 367.856 324.334 363.513 298.763C359.169 273.191 357.053 242.836 352.845 211.886C344.425 149.984 326.933 84.013 263.105 50.851C226.15 31.651 184.013 22.274 144.733 22.038L144.734 22.04ZM144.611 40.05C181.073 40.305 220.721 49.115 254.808 66.824C311.201 96.124 326.802 153.964 335.011 214.312C339.115 244.487 341.197 274.866 345.769 301.777C347.085 309.53 348.604 317.019 350.462 324.162C335.014 324.202 323.208 315.855 308.758 299.445C316.143 329.855 320.748 335.979 334.463 354.995C306.243 346.76 273.823 320.255 253.513 290.932C250.239 330.979 273.736 362.506 286.788 374.862C261.612 360.666 226.075 333.326 202.165 286.207C201.149 327.633 214.095 373.939 238.615 402.672C204.1 391.136 173.645 303.2 153.195 275.039C140.155 308.256 150.247 364.124 169.267 405.161C149.639 382.323 138.38 355.786 132.712 328.565C121.188 273.223 134.462 214.718 151.037 184.327C170.587 148.485 161.952 112.577 140.187 91.601C118.419 70.625 66 81 53.633 83.286C41.266 85.572 31 83.286 31 83.286C31 83.286 41.3371 75.1684 48 70C74.6656 49.3155 88.786 42.954 129.211 40.461C134.263 40.149 139.406 40.011 144.614 40.047L144.611 40.05Z" fill="url(#paint0_linear_1104_3)"/>
<defs>
<linearGradient id="paint0_linear_1104_3" x1="384.5" y1="480" x2="256" y2="256" gradientUnits="userSpaceOnUse">
<stop stop-color="#FF6011"/>
<stop offset="1" stop-color="#FF9411"/>
</linearGradient>
</defs>
</svg>

Before

Width:  |  Height:  |  Size: 2.4 KiB

View File

@@ -1,21 +0,0 @@
import express from 'express';
import cors from 'cors';
import { useUserRoute } from './service/route/user.js';
import { useAppRoute } from './service/route/app.js';
import { useKbRoute } from './service/route/kb.js';
import { useSystemRoute } from './service/route/system.js';
const app = express();
app.use(cors());
app.use(express.json());
app.use(express.static('dist'));
useUserRoute(app);
useAppRoute(app);
useKbRoute(app);
useSystemRoute(app);
const PORT = process.env.PORT || 3001;
app.listen(PORT, () => {
console.log(`Server is running on port ${PORT}`);
});

View File

@@ -1,57 +0,0 @@
import { User, Model, Kb } from '../schema.js';
import { auth } from './system.js';
export const useAppRoute = (app) => {
// 获取AI助手列表
app.get('/models', auth(), async (req, res) => {
try {
const start = parseInt(req.query._start) || 0;
const end = parseInt(req.query._end) || 20;
const order = req.query._order === 'DESC' ? -1 : 1;
const sort = req.query._sort || '_id';
const userId = req.query.userId || '';
const name = req.query.name || '';
const where = {
...(userId ? { userId: userId } : {}),
name
};
const modelsRaw = await Model.find()
.skip(start)
.limit(end - start)
.sort({ [sort]: order });
const models = [];
for (const modelRaw of modelsRaw) {
const model = modelRaw.toObject();
// 获取与模型关联的知识库名称
const kbNames = [];
for (const kbId of model.chat.relatedKbs) {
const kb = await Kb.findById(kbId);
kbNames.push(kb.name);
}
const orderedModel = {
id: model._id.toString(),
userId: model.userId,
name: model.name,
relatedKbs: kbNames, // 将relatedKbs的id转换为相应的Kb名称
searchMode: model.chat?.searchMode,
systemPrompt: model.chat?.systemPrompt || '',
temperature: model.chat?.temperature
};
models.push(orderedModel);
}
const totalCount = await Model.countDocuments();
res.header('Access-Control-Expose-Headers', 'X-Total-Count');
res.header('X-Total-Count', totalCount);
res.json(models);
} catch (err) {
console.log(`Error fetching models: ${err}`);
res.status(500).json({ error: 'Error fetching models', details: err.message });
}
});
};

View File

@@ -1,44 +0,0 @@
import { Kb } from '../schema.js';
import { auth } from './system.js';
export const useKbRoute = (app) => {
// 获取用户知识库列表
app.get('/kbs', auth(), async (req, res) => {
try {
const start = parseInt(req.query._start) || 0;
const end = parseInt(req.query._end) || 20;
const order = req.query._order === 'DESC' ? -1 : 1;
const sort = req.query._sort || '_id';
const tag = req.query.tag || '';
const where = { tags: { $elemMatch: { $regex: tag, $options: 'i' } } };
const kbsRaw = await Kb.find(where)
.skip(start)
.limit(end - start)
.sort({ [sort]: order });
const kbs = [];
for (const kbRaw of kbsRaw) {
const kb = kbRaw.toObject();
const orderedKb = {
id: kb._id.toString(),
userId: kb.userId,
name: kb.name,
tags: kb.tags,
avatar: kb.avatar
};
kbs.push(orderedKb);
}
const totalCount = await Kb.countDocuments(where);
res.header('Access-Control-Expose-Headers', 'X-Total-Count');
res.header('X-Total-Count', totalCount);
res.json(kbs);
} catch (err) {
console.log(`Error fetching kbs: ${err}`);
res.status(500).json({ error: 'Error fetching kbs', details: err.message });
}
});
};

View File

@@ -1,134 +0,0 @@
import jwt from 'jsonwebtoken';
import { System } from '../schema.js';
const adminAuth = {
username: process.env.ADMIN_USER,
password: process.env.ADMIN_PASS
};
const authSecret = process.env.ADMIN_SECRET;
const postParent = () => {
fetch(`${process.env.PARENT_URL}/api/system/updateEnv`, {
headers: {
rootkey: process.env.PARENT_ROOT_KEY
}
});
};
export const useSystemRoute = (app) => {
app.post('/api/login', (req, res) => {
if (!adminAuth.username || !adminAuth.password) {
res.status(401).end('Server not set env: ADMIN_USER, ADMIN_PASS');
return;
}
const { username, password } = req.body;
if (username === adminAuth.username && password === adminAuth.password) {
// 用户名和密码都正确返回token
const token = jwt.sign(
{
username,
platform: 'admin'
},
authSecret,
{
expiresIn: '2h'
}
);
res.json({
username,
token: token,
expiredAt: new Date().valueOf() + 2 * 60 * 60 * 1000
});
} else {
res.status(401).end('username or password incorrect');
}
});
app.get('/system', auth(), async (req, res) => {
try {
const data = await System.find();
const totalCount = await System.countDocuments();
res.header('Access-Control-Expose-Headers', 'X-Total-Count');
res.header('X-Total-Count', totalCount);
res.json(
data.map((item) => {
const obj = item.toObject();
return {
...obj,
id: obj._id
};
})
);
} catch (error) {
console.log(error);
res.status(500).json({ error: 'Error creating system env' });
}
});
app.post('/system', auth(), async (req, res) => {
try {
await System.create({
...req.body,
sensitiveCheck: req.body.sensitiveCheck === 'true'
});
postParent();
res.json({});
} catch (error) {
res.status(500).json({ error: 'Error creating system env' });
}
});
app.put('/system/:id', auth(), async (req, res) => {
try {
const _id = req.params.id;
await System.findByIdAndUpdate(_id, {
...req.body,
sensitiveCheck: req.body.sensitiveCheck === 'true'
});
postParent();
res.json({});
} catch (error) {
res.status(500).json({ error: 'Error updating system env' });
}
});
app.delete('/system/:id', auth(), async (req, res) => {
try {
const _id = req.params.id;
await System.findByIdAndDelete(_id);
res.json({});
} catch (error) {
res.status(500).json({ error: 'Error updating system env' });
}
});
};
export const auth = () => {
return (req, res, next) => {
try {
const authorization = req.headers.authorization;
if (!authorization) {
res.status(401).end('not found authorization in headers');
return;
}
const token = authorization.slice('Bearer '.length);
const payload = jwt.verify(token, authSecret);
if (typeof payload === 'string') {
res.status(401).end('payload type error');
return;
}
if (payload.platform !== 'admin') {
res.status(401).end('Payload invalid');
return;
}
next();
} catch (err) {
res.status(401).end(String(err));
}
};
};

View File

@@ -1,136 +0,0 @@
import { User, Pay } from '../schema.js';
import dayjs from 'dayjs';
import { auth } from './system.js';
import crypto from 'crypto';
// 加密
const hashPassword = (psw) => {
return crypto.createHash('sha256').update(psw).digest('hex');
};
export const useUserRoute = (app) => {
// 获取用户列表
app.get('/users', auth(), async (req, res) => {
try {
const start = parseInt(req.query._start) || 0;
const end = parseInt(req.query._end) || 20;
const order = req.query._order === 'DESC' ? -1 : 1;
const sort = req.query._sort || 'createTime';
const username = req.query.username || '';
const where = {
username: { $regex: username, $options: 'i' }
};
const usersRaw = await User.find(where)
.skip(start)
.limit(end - start)
.sort({ [sort]: order });
const users = usersRaw.map((user) => {
const obj = user.toObject();
return {
...obj,
id: obj._id,
createTime: dayjs(obj.createTime).format('YYYY/MM/DD HH:mm'),
password: ''
};
});
const totalCount = await User.countDocuments(where);
res.header('Access-Control-Expose-Headers', 'X-Total-Count');
res.header('X-Total-Count', totalCount);
res.json(users);
} catch (err) {
console.log(`Error fetching users: ${err}`);
res.status(500).json({ error: 'Error fetching users' });
}
});
// 创建用户
app.post('/users', auth(), async (req, res) => {
try {
const { username, password, balance } = req.body;
if (!username || !password || !balance) {
return res.status(400).json({ error: 'Invalid user information' });
}
const existingUser = await User.findOne({ username });
if (existingUser) {
return res.status(400).json({ error: 'Username already exists' });
}
const result = await User.create({
username,
password,
balance
});
res.json(result);
} catch (err) {
console.log(`Error creating user: ${err}`);
res.status(500).json({ error: 'Error creating user' });
}
});
// 修改用户信息
app.put('/users/:id', auth(), async (req, res) => {
try {
const _id = req.params.id;
let { password, balance = 0 } = req.body;
const result = await User.findByIdAndUpdate(_id, {
...(password && { password: hashPassword(hashPassword(password)) }),
...(balance && { balance })
});
res.json(result);
} catch (err) {
console.log(`Error updating user: ${err}`);
res.status(500).json({ error: 'Error updating user' });
}
});
// 新增: 获取 pays 列表
app.get('/pays', auth(), async (req, res) => {
try {
const start = parseInt(req.query._start) || 0;
const end = parseInt(req.query._end) || 20;
const order = req.query._order === 'DESC' ? -1 : 1;
const sort = req.query._sort || '_id';
const userId = req.query.userId || '';
const where = userId ? { userId: userId } : {};
const paysRaw = await Pay.find({
...where
})
.skip(start)
.limit(end - start)
.sort({ [sort]: order });
const pays = [];
for (const payRaw of paysRaw) {
const pay = payRaw.toObject();
const orderedPay = {
id: pay._id.toString(),
userId: pay.userId,
price: pay.price,
orderId: pay.orderId,
status: pay.status,
createTime: dayjs(pay.createTime).format('YYYY/MM/DD HH:mm')
};
pays.push(orderedPay);
}
const totalCount = await Pay.countDocuments({
...where
});
res.header('Access-Control-Expose-Headers', 'X-Total-Count');
res.header('X-Total-Count', totalCount);
res.json(pays);
} catch (err) {
console.log(`Error fetching pays: ${err}`);
res.status(500).json({ error: 'Error fetching pays', details: err.message });
}
});
};

View File

@@ -1,122 +0,0 @@
import mongoose from 'mongoose';
import dotenv from 'dotenv';
dotenv.config({ path: '.env.local' });
const mongoUrl = process.env.MONGODB_URI;
const mongoDBName = process.env.MONGODB_NAME;
if (!mongoUrl || !mongoDBName) {
throw new Error('db error');
}
mongoose
.connect(mongoUrl, {
dbName: mongoDBName,
bufferCommands: true,
maxPoolSize: 5,
minPoolSize: 1,
maxConnecting: 5
})
.then(() => console.log('Connected to MongoDB successfully!'))
.catch((err) => console.log(`Error connecting to MongoDB: ${err}`));
const userSchema = new mongoose.Schema({
_id: mongoose.Schema.Types.ObjectId,
username: String,
password: String,
balance: Number,
promotion: {
rate: Number
},
openaiKey: String,
avatar: String,
createTime: Date
});
// 新增: 定义 pays 模型
const paySchema = new mongoose.Schema({
_id: mongoose.Schema.Types.ObjectId,
userId: mongoose.Schema.Types.ObjectId,
price: Number,
orderId: String,
status: String,
createTime: Date,
__v: Number
});
// 新增: 定义 kb 模型
const kbSchema = new mongoose.Schema({
_id: mongoose.Schema.Types.ObjectId,
userId: mongoose.Schema.Types.ObjectId,
avatar: String,
name: String,
tags: [String],
updateTime: Date,
__v: Number
});
const modelSchema = new mongoose.Schema({
userId: mongoose.Schema.Types.ObjectId,
name: String,
avatar: String,
status: String,
chat: {
relatedKbs: [mongoose.Schema.Types.ObjectId],
searchMode: String,
systemPrompt: String,
temperature: Number,
chatModel: String
},
share: {
isShare: Boolean,
isShareDetail: Boolean,
intro: String,
collection: Number
},
security: {
domain: [String],
contextMaxLen: Number,
contentMaxLen: Number,
expiredTime: Number,
maxLoadAmount: Number
},
updateTime: Date
});
const SystemSchema = new mongoose.Schema({
openAIKeys: {
type: String,
default: ''
},
openAITrainingKeys: {
type: String,
default: ''
},
gpt4Key: {
type: String,
default: ''
},
vectorMaxProcess: {
type: Number,
default: 10
},
qaMaxProcess: {
type: Number,
default: 10
},
pgIvfflatProbe: {
type: Number,
default: 10
},
sensitiveCheck: {
type: Boolean,
default: false
}
});
export const Model = mongoose.models['model'] || mongoose.model('model', modelSchema);
export const Kb = mongoose.models['kb'] || mongoose.model('kb', kbSchema);
export const User = mongoose.models['user'] || mongoose.model('user', userSchema);
export const Pay = mongoose.models['pay'] || mongoose.model('pay', paySchema);
export const System = mongoose.models['system'] || mongoose.model('system', SystemSchema);

View File

@@ -1,105 +0,0 @@
import {
createTextField,
jsonServerProvider,
ListTable,
Resource,
Tushan,
fetchJSON
} from 'tushan';
import { authProvider } from './auth';
import { userFields, payFields, kbFields, ModelFields, SystemFields } from './fields';
import { Dashboard } from './Dashboard';
const authStorageKey = 'tushan:auth';
const httpClient: typeof fetchJSON = (url, options = {}) => {
try {
if (!options.headers) {
options.headers = new Headers({ Accept: 'application/json' });
}
const { token } = JSON.parse(window.localStorage.getItem(authStorageKey) ?? '{}');
(options.headers as Headers).set('Authorization', `Bearer ${token}`);
return fetchJSON(url, options);
} catch (err) {
return Promise.reject();
}
};
const dataProvider = jsonServerProvider(import.meta.env.VITE_PUBLIC_SERVER_URL, httpClient);
function App() {
return (
<Tushan
basename="/"
header={'FastGpt-Admin'}
dataProvider={dataProvider}
authProvider={authProvider}
dashboard={<Dashboard />}
>
<Resource
name="users"
label="用户信息"
list={
<ListTable
filter={[
createTextField('username', {
label: 'username'
})
]}
fields={userFields}
action={{ detail: true, edit: true }}
/>
}
/>
<Resource
name="pays"
label="支付记录"
list={
<ListTable
filter={[
createTextField('userId', {
label: 'userId'
})
]}
fields={payFields}
action={{ detail: true }}
/>
}
/>
<Resource
name="kbs"
label="知识库"
list={
<ListTable
filter={[
createTextField('tag', {
label: 'tag'
})
]}
fields={kbFields}
action={{ detail: true }}
/>
}
/>
<Resource
name="models"
label="应用"
list={<ListTable fields={ModelFields} action={{ detail: true }} />}
/>
<Resource
name="system"
label="系统"
list={
<ListTable
fields={SystemFields}
action={{ detail: true, edit: true, create: true, delete: true }}
/>
}
/>
</Tushan>
);
}
export default App;

View File

@@ -1,143 +0,0 @@
import { Card, Link, Space, Grid, Divider, Typography } from '@arco-design/web-react';
import { IconApps, IconUser, IconUserGroup } from 'tushan/icon';
import React, { useState, useEffect } from 'react';
import { useTranslation } from 'react-i18next';
const authStorageKey = 'tushan:auth';
export const Dashboard: React.FC = React.memo(() => {
const [userCount, setUserCount] = useState(0); //用户数量
const [kbCount, setkbCount] = useState(0);
const [modelCount, setmodelCount] = useState(0);
useEffect(() => {
const fetchCounts = async () => {
const baseUrl = import.meta.env.VITE_PUBLIC_SERVER_URL;
const { token } = JSON.parse(window.localStorage.getItem(authStorageKey) ?? '{}');
const headers = {
'Content-Type': 'application/json',
Authorization: `Bearer ${token}`
};
const userResponse = await fetch(`${baseUrl}/users?_end=1`, {
headers
});
const kbResponse = await fetch(`${baseUrl}/kbs?_end=1`, {
headers
});
const modelResponse = await fetch(`${baseUrl}/models?_end=1`, {
headers
});
const userTotalCount = userResponse.headers.get('X-Total-Count');
const kbTotalCount = kbResponse.headers.get('X-Total-Count');
const modelTotalCount = modelResponse.headers.get('X-Total-Count');
console.log(userTotalCount);
if (userTotalCount) {
setUserCount(Number(userTotalCount));
}
if (kbTotalCount) {
setkbCount(Number(kbTotalCount));
}
if (modelTotalCount) {
setmodelCount(Number(modelTotalCount));
}
};
fetchCounts();
}, []);
return (
<div>
<div>
<Space direction="vertical" style={{ width: '100%' }}>
<Card bordered={false}>
<Typography.Title heading={5}>FastGpt Admin</Typography.Title>
<Divider />
<Grid.Row justify="center">
<Grid.Col flex={1} style={{ paddingLeft: '1rem' }}>
{/* 把 userCount 传递给 DataItem 组件 */}
<DataItem icon={<IconUser />} title={'用户'} count={userCount} />
</Grid.Col>
<Divider type="vertical" style={{ height: 40 }} />
<Grid.Col flex={1} style={{ paddingLeft: '1rem' }}>
<DataItem icon={<IconUserGroup />} title={'知识库'} count={kbCount} />
</Grid.Col>
<Divider type="vertical" style={{ height: 40 }} />
<Grid.Col flex={1} style={{ paddingLeft: '1rem' }}>
<DataItem icon={<IconApps />} title={'AI模型'} count={modelCount} />
</Grid.Col>
</Grid.Row>
<Divider />
</Card>
</Space>
</div>
</div>
);
});
Dashboard.displayName = 'Dashboard';
const DashboardItem: React.FC<
React.PropsWithChildren<{
title: string;
href?: string;
}>
> = React.memo((props) => {
const { t } = useTranslation();
return (
<Card
title={props.title}
extra={
props.href && (
<Link target="_blank" href={props.href}>
{t('tushan.dashboard.more')}
</Link>
)
}
bordered={false}
style={{ overflow: 'hidden' }}
>
{props.children}
</Card>
);
});
DashboardItem.displayName = 'DashboardItem';
const DataItem: React.FC<{
icon: React.ReactElement;
title: string;
count: number;
}> = React.memo((props) => {
return (
<Space>
<div
style={{
fontSize: 20,
padding: '0.5rem',
borderRadius: '9999px',
border: '1px solid #ccc',
width: 24,
height: 24,
display: 'flex',
justifyContent: 'center',
alignItems: 'center'
}}
>
{props.icon}
</div>
<div>
<div style={{ fontWeight: 700 }}>{props.title}</div>
<div>{props.count}</div>
</div>
</Space>
);
});
DataItem.displayName = 'DataItem';

View File

@@ -1,5 +0,0 @@
import { createAuthProvider, type AuthProvider } from 'tushan';
export const authProvider: AuthProvider = createAuthProvider({
loginUrl: `${import.meta.env.VITE_PUBLIC_SERVER_URL}/api/login`
});

View File

@@ -1,50 +0,0 @@
import { createTextField, createNumberField } from 'tushan';
export const userFields = [
createTextField('id', { label: 'ID' }),
createTextField('username', { label: '用户名' }),
createNumberField('balance', { label: '余额', list: { sort: true } }),
createTextField('createTime', { label: 'Create Time', list: { sort: true } }),
createTextField('password', { label: '密码', list: { hidden: true } })
];
export const payFields = [
createTextField('id', { label: 'ID' }),
createTextField('userId', { label: '用户Id' }),
createNumberField('price', { label: '支付金额' }),
createTextField('orderId', { label: 'orderId' }),
createTextField('status', { label: '状态' }),
createTextField('createTime', { label: 'Create Time', list: { sort: true } })
];
export const kbFields = [
createTextField('id', { label: 'ID' }),
createTextField('userId', { label: '所属用户' }),
createTextField('name', { label: '知识库' }),
createTextField('tags', { label: 'Tags' })
];
export const ModelFields = [
createTextField('id', { label: 'ID' }),
createTextField('userId', { label: '所属用户' }),
createTextField('name', { label: '名字' }),
createTextField('relatedKbs', { label: '引用的知识库' }),
createTextField('searchMode', { label: '搜索模式' }),
createTextField('systemPrompt', {
label: '提示词',
list: {
width: 400
}
}),
createTextField('temperature', { label: '温度' })
];
export const SystemFields = [
createTextField('openAIKeys', { label: 'openAIKeys逗号隔开' }),
createTextField('openAITrainingKeys', { label: 'openAITrainingKeys' }),
createTextField('gpt4Key', { label: 'gpt4Key' }),
createTextField('vectorMaxProcess', { label: '向量最大进程' }),
createTextField('qaMaxProcess', { label: 'qa最大进程' }),
createTextField('pgIvfflatProbe', { label: 'pg 探针数量' }),
createTextField('sensitiveCheck', { label: '敏感词校验(true,false)' })
];

View File

@@ -1,5 +0,0 @@
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render(<App />);

View File

@@ -1 +0,0 @@
/// <reference types="vite/client" />

View File

@@ -1,21 +0,0 @@
{
"compilerOptions": {
"target": "ESNext",
"useDefineForClassFields": true,
"lib": ["DOM", "DOM.Iterable", "ESNext"],
"allowJs": false,
"skipLibCheck": true,
"esModuleInterop": false,
"allowSyntheticDefaultImports": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"module": "ESNext",
"moduleResolution": "Node",
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "react-jsx"
},
"include": ["src"],
"references": [{ "path": "./tsconfig.node.json" }]
}

View File

@@ -1,9 +0,0 @@
{
"compilerOptions": {
"composite": true,
"module": "ESNext",
"moduleResolution": "Node",
"allowSyntheticDefaultImports": true
},
"include": ["vite.config.ts"]
}

View File

@@ -1,7 +0,0 @@
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
// https://vitejs.dev/config/
export default defineConfig({
plugins: [react()],
});

21
client/.env.template Normal file
View File

@@ -0,0 +1,21 @@
# 默认用户密码,用户名为 root每次重启时会自动更新。
DEFAULT_ROOT_PSW=123456
# 代理
# AXIOS_PROXY_HOST=127.0.0.1
# AXIOS_PROXY_PORT=7890
# 数据库最大连接数
DB_MAX_LINK=5
# token
TOKEN_KEY=dfdasfdas
# root key, 最高权限
ROOT_KEY=fdafasd
# openai 基本地址,可用作中转。
OPENAI_BASE_URL=https://api.openai.com/v1
# oneapi 地址,可以使用 oneapi 来实现多模型接入
# ONEAPI_URL=https://xxxx.cloud.sealos.io/openai/v1
# 通用key。可以是 openai 的也可以是 oneapi 的。
# 此处逻辑:优先走 ONEAPI_URL如果填写了 ONEAPI_URLkey 也需要是 ONEAPI 的 key
CHAT_API_KEY=sk-xxxx
# db
MONGODB_URI=mongodb://username:password@0.0.0.0:27017/fastgpt
PG_URL=postgresql://username:password@host:port/postgres

3
client/.gitignore vendored
View File

@@ -28,4 +28,5 @@ next-env.d.ts
platform.json
testApi/
local/
.husky/
.husky/
data/*.local.*

View File

@@ -5,16 +5,18 @@ RUN apk add --no-cache libc6-compat && npm install -g pnpm
WORKDIR /app
# Install dependencies based on the preferred package manager
COPY package.json pnpm-lock.yaml* ./
RUN pnpm config set registry https://registry.npmmirror.com/
COPY package.json ./
COPY pnpm-lock.yaml* ./
RUN \
[ -f pnpm-lock.yaml ] && pnpm install || \
[ -f pnpm-lock.yaml ] && pnpm fetch || \
(echo "Lockfile not found." && exit 1)
# Rebuild the source code only when needed
FROM node:current-alpine AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY pnpm-lock.yaml* ./
COPY package.json ./
COPY . .
# Next.js collects completely anonymous telemetry data about general usage.
@@ -22,7 +24,10 @@ COPY . .
# Uncomment the following line in case you want to disable telemetry during the build.
ENV NEXT_TELEMETRY_DISABLED 1
RUN npm install -g pnpm && pnpm run build
RUN npm install -g pnpm
RUN \
[ -f pnpm-lock.yaml ] && (pnpm --offline install && pnpm run build) || \
(echo "Lockfile not found." && exit 1)
# Production image, copy all the files and run next
FROM node:current-alpine AS runner

63
client/data/config.json Normal file
View File

@@ -0,0 +1,63 @@
{
"FeConfig": {
"show_emptyChat": true,
"show_register": false,
"show_appStore": false,
"show_userDetail": false,
"show_git": true,
"systemTitle": "FastGPT",
"authorText": "Made by FastGPT Team.",
"gitLoginKey": "",
"scripts": []
},
"SystemParams": {
"gitLoginSecret": "",
"vectorMaxProcess": 15,
"qaMaxProcess": 15,
"pgIvfflatProbe": 20
},
"ChatModels": [
{
"model": "gpt-3.5-turbo",
"name": "GPT35-4k",
"contextMaxToken": 4000,
"quoteMaxToken": 2000,
"maxTemperature": 1.2,
"price": 0,
"defaultSystem": ""
},
{
"model": "gpt-3.5-turbo-16k",
"name": "GPT35-16k",
"contextMaxToken": 16000,
"quoteMaxToken": 8000,
"maxTemperature": 1.2,
"price": 0,
"defaultSystem": ""
},
{
"model": "gpt-4",
"name": "GPT4-8k",
"contextMaxToken": 8000,
"quoteMaxToken": 4000,
"maxTemperature": 1.2,
"price": 0,
"defaultSystem": ""
}
],
"QAModels": [
{
"model": "gpt-3.5-turbo-16k",
"name": "GPT35-16k",
"maxToken": 16000,
"price": 0
}
],
"VectorModels": [
{
"model": "text-embedding-ada-002",
"name": "Embedding-2",
"price": 0
}
]
}

View File

@@ -0,0 +1,12 @@
//next-i18next.config.js
/**
* @type {import('next-i18next').UserConfig}
*/
module.exports = {
i18n: {
defaultLocale: 'en',
locales: ['en', 'zh', 'zh-Hans'],
localeDetection: false
}
};

View File

@@ -1,22 +1,37 @@
/** @type {import('next').NextConfig} */
const { i18n } = require('./next-i18next.config');
const nextConfig = {
i18n,
output: 'standalone',
reactStrictMode: false,
compress: true,
webpack(config) {
webpack(config, { isServer }) {
if (!isServer) {
config.resolve = {
...config.resolve,
fallback: {
...config.resolve.fallback,
fs: false
}
};
}
config.experiments = {
asyncWebAssembly: true,
layers: true
};
config.module.rules = config.module.rules.concat([
{
test: /\.svg$/i,
issuer: /\.[jt]sx?$/,
use: ['@svgr/webpack']
}
]);
config.module = {
...config.module,
rules: config.module.rules.concat([
{
test: /\.svg$/i,
issuer: /\.[jt]sx?$/,
use: ['@svgr/webpack']
}
]),
exprContextCritical: false
};
return config;
}

View File

@@ -9,46 +9,50 @@
"lint": "next lint"
},
"dependencies": {
"@alicloud/dysmsapi20170525": "^2.0.23",
"@alicloud/openapi-client": "^0.4.5",
"@alicloud/tea-util": "^1.4.5",
"@chakra-ui/icons": "^2.0.17",
"@chakra-ui/react": "^2.5.1",
"@chakra-ui/system": "^2.5.5",
"@dqbd/tiktoken": "^1.0.6",
"@chakra-ui/react": "^2.7.0",
"@chakra-ui/system": "^2.5.8",
"@dqbd/tiktoken": "^1.0.7",
"@emotion/react": "^11.10.6",
"@emotion/styled": "^11.10.6",
"@mozilla/readability": "^0.4.4",
"@next/font": "13.1.6",
"@tanstack/react-query": "^4.24.10",
"@types/nprogress": "^0.2.0",
"axios": "^1.3.3",
"cookie": "^0.5.0",
"crypto": "^1.0.1",
"date-fns": "^2.30.0",
"dayjs": "^1.11.7",
"eventsource-parser": "^0.1.0",
"echarts": "^5.4.1",
"formidable": "^2.1.1",
"framer-motion": "^9.0.6",
"graphemer": "^1.4.0",
"hyperdown": "^2.4.29",
"i18next": "^22.5.1",
"immer": "^9.0.19",
"js-cookie": "^3.0.5",
"jsdom": "^22.1.0",
"jsonwebtoken": "^9.0.0",
"lodash": "^4.17.21",
"mammoth": "^1.5.1",
"mermaid": "^8.13.5",
"mermaid": "^10.2.3",
"mongoose": "^6.10.0",
"nanoid": "^4.0.1",
"next": "13.1.6",
"next-i18next": "^13.3.0",
"nextjs-cors": "^2.1.2",
"nodemailer": "^6.9.1",
"nprogress": "^0.2.0",
"openai": "^3.2.1",
"openai": "^3.3.0",
"papaparse": "^5.4.1",
"pg": "^8.10.0",
"react": "18.2.0",
"react-day-picker": "^8.7.1",
"react-dom": "18.2.0",
"react-hook-form": "^7.43.1",
"react-markdown": "^8.0.5",
"react-i18next": "^12.3.1",
"react-markdown": "^8.0.7",
"react-syntax-highlighter": "^15.5.0",
"reactflow": "^11.7.4",
"rehype-katex": "^6.0.2",
"remark-breaks": "^3.0.3",
"remark-gfm": "^3.0.1",
@@ -56,17 +60,19 @@
"request-ip": "^3.3.0",
"sass": "^1.58.3",
"tunnel": "^0.0.6",
"wxpay-v3": "^3.0.2",
"winston": "^3.10.0",
"winston-mongodb": "^5.1.1",
"zustand": "^4.3.5"
},
"devDependencies": {
"@svgr/webpack": "^6.5.1",
"@types/cookie": "^0.5.1",
"@types/formidable": "^2.0.5",
"@types/js-cookie": "^3.0.3",
"@types/jsdom": "^21.1.1",
"@types/jsonwebtoken": "^9.0.1",
"@types/lodash": "^4.14.191",
"@types/node": "18.14.0",
"@types/nodemailer": "^6.4.7",
"@types/papaparse": "^5.3.7",
"@types/pg": "^8.6.6",
"@types/react": "18.0.28",

3530
client/pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,26 +1,21 @@
### 常见问题
**Git 地址**
[项目地址,完全开源,随便用。](https://github.com/c121914yu/FastGPT)
**问题文档**
[先看文档,再提问](https://kjqvjse66l.feishu.cn/docx/HtrgdT0pkonP4kxGx8qcu6XDnGh)
**删除和复制**
电脑端:聊天内容右侧有复制和删除的图标。
移动端:点击对话头像,可以选择复制或删除该条内容。
- [**Git 地址**,点击查看项目地址](https://github.com/labring/FastGPT)
- [本地部署 FastGPT](https://doc.fastgpt.run/docs/installation)
- [API 文档](https://kjqvjse66l.feishu.cn/docx/DmLedTWtUoNGX8xui9ocdUEjnNh?pre_pathname=%2Fdrive%2Fhome%2F)
- **反馈问卷**: 如果你遇到任何使用问题或有期望的功能,可以[填写该问卷](https://www.wjx.cn/vm/rLIw1uD.aspx#)
- **问题文档**: [先看文档,再提问](https://kjqvjse66l.feishu.cn/docx/HtrgdT0pkonP4kxGx8qcu6XDnGh)
**价格表**
如果使用了自己的 Api Key网页上 openai 模型聊天不会计费。可以在账号页,看到详细账单。
| 计费项 | 价格: 元/ 1K tokens包含上下文|
| --- | --- |
| 知识库 - 索引 | 0.001 |
| chatgpt - 对话 | 0.025 |
| gpt4 - 对话 | 0.5 |
| 文件拆分 | 0.025 |
| 知识库 - 索引 | 0.002 |
| FastAI4k - 对话 | 0.015 |
| FastAI16k - 对话 | 0.03 |
| FastAI-Plus - 对话 | 0.45 |
| 文件拆分 | 0.03 |
**其他问题**
请 WX 联系: YNyiqi
| 交流群 | 小助手 |
| ----------------------- | -------------------- |
| ![](https://otnvvf-imgs.oss.laf.run/wxqun300.jpg) | ![](https://otnvvf-imgs.oss.laf.run/wx300.jpg) |

View File

@@ -1,9 +0,0 @@
接受一个 csv 文件,表格头包含 question 和 answer。question 代表问题answer 代表答案。
导入前会进行去重,如果问题和答案完全相同,则不会被导入,所以最终导入的内容可能会比文件的内容少。但是,对于带有换行的内容,目前无法去重。
### 请保证 csv 文件为 utf-8 编码
| question | answer |
| ------------- | ------------------------------------------------------ |
| 什么是 laf | laf 是一个云函数开发平台…… |
| 什么是 sealos | Sealos 是以 kubernetes 为内核的云操作系统发行版,可以…… |

View File

@@ -1,33 +0,0 @@
## 欢迎使用 Fast GPT
### 项目开源
FastGpt 项目完全开源,可随意私有化部署,去除平台风险忧虑。项目地址:[Git 仓库](https://github.com/c121914yu/FastGPT)
### 开始使用知识库
1. AI 助手详情里,有一个模型效果。打开知识库搜索开关即可使用知识库搜索功能。
2. 导入知识库数据。可以手动输入或文件导入。
3. 开始对话。
4. 对话结束后,会看到聊天下方有一个“查看提示词”,可以看到搜索到了哪些内容。
注意使用知识库模型对话时tokens 消耗会加快。
### 价格表
如果使用了自己的 Api Key网页上 openai 模型聊天不会计费。可以在账号页,看到详细账单。
| 计费项 | 价格: 元/ 1K tokens包含上下文|
| --- | --- |
| 知识库 - 索引 | 0.001 |
| chatgpt - 对话 | 0.025 |
| gpt4 - 对话 | 0.5 |
| 文件拆分 | 0.025 |
### 交流群/问题反馈
如果群满了,可加个小助手,定时拉
wx 号: YNyiqi
| 交流群 | 小助手 |
| ------------------------------------------------- | ---------------------------------------------- |
| ![](https://otnvvf-imgs.oss.laf.run/wxqun300.jpg) | ![](https://otnvvf-imgs.oss.laf.run/wx300.jpg) |

View File

@@ -1,3 +0,0 @@
你正准备分享对话,请确保分享链接不会滥用,因为它是使用的是你的 API key。
* 分享空白对话:为该模型创建一个空白的聊天分享出去。
* 分享当前对话:会把当前聊天的内容也分享出去,但是要注意不要多个人同时用一个聊天内容。

View File

@@ -1,4 +1,8 @@
### Fast GPT V3.8.3
### Fast GPT V4.2
1. 新增 - mermaid 导图兼容,可以在应用市场 'mermaid 导图' 进行体验。
2. 优化 - 部分 UI 和账号页。
1. 新增 - 应用日志初版,可观测到所有对话记录
2. 新增 - 好友邀请链接,[点击查看](/account?currentTab=promotion)
3. 新增 - Iframe 嵌入页面图标可拖拽
4. 优化 - 知识库搜索提示词
5. 优化 - [使用文档](https://doc.fastgpt.run/docs/intro/)
6. [点击查看高级编排介绍文档](https://doc.fastgpt.run/docs/workflow)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 52 KiB

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 38 KiB

After

Width:  |  Height:  |  Size: 8.3 KiB

599
client/public/icon/logo.svg Normal file
View File

@@ -0,0 +1,599 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="256px" height="256px" viewBox="0 0 256 256" enable-background="new 0 0 256 256" xml:space="preserve"> <image id="image0" width="256" height="256" x="0" y="0"
href="data:image/png;base64,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
MDqUEekAAAAASUVORK5CYII=" />
</svg>

After

Width:  |  Height:  |  Size: 45 KiB

View File

Before

Width:  |  Height:  |  Size: 38 KiB

After

Width:  |  Height:  |  Size: 38 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

View File

@@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1689493855879" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3538" xmlns:xlink="http://www.w3.org/1999/xlink" width="64" height="64"><path d="M145.6 0C100.8 0 64 36.8 64 81.6v860.8C64 987.2 100.8 1024 145.6 1024h732.8c44.8 0 81.6-36.8 81.6-81.6V324.8L656 0H145.6z" fill="#45B058" p-id="3539"></path><path d="M388.8 691.2c1.6 1.6 3.2 4.8 3.2 8 0 6.4-4.8 11.2-11.2 11.2-3.2 0-6.4 0-8-3.2-11.2-12.8-30.4-22.4-48-22.4-41.6 0-73.6 32-73.6 78.4 0 44.8 32 78.4 73.6 78.4 17.6 0 35.2-8 48-22.4 1.6-1.6 4.8-3.2 8-3.2 6.4 0 11.2 4.8 11.2 11.2 0 3.2-1.6 6.4-3.2 8-14.4 16-35.2 27.2-64 27.2-56 0-99.2-40-99.2-99.2s43.2-99.2 99.2-99.2c28.8 0 49.6 11.2 64 27.2z m108.8 171.2c-28.8 0-51.2-9.6-67.2-24-3.2-1.6-3.2-4.8-3.2-8 0-6.4 3.2-12.8 11.2-12.8 1.6 0 4.8 1.6 6.4 3.2 12.8 11.2 32 20.8 54.4 20.8 33.6 0 44.8-19.2 44.8-33.6 0-49.6-113.6-22.4-113.6-91.2 0-30.4 27.2-52.8 65.6-52.8 24 0 46.4 8 62.4 20.8 1.6 1.6 3.2 4.8 3.2 8 0 6.4-4.8 11.2-11.2 11.2-1.6 0-4.8 0-6.4-1.6-14.4-11.2-32-17.6-49.6-17.6-24 0-40 12.8-40 30.4 0 43.2 113.6 19.2 113.6 91.2 0 27.2-19.2 56-70.4 56z m272-179.2L702.4 848c-3.2 8-9.6 12.8-17.6 12.8h-1.6c-8 0-16-4.8-19.2-12.8l-65.6-164.8c-1.6-1.6-1.6-3.2-1.6-4.8 0-6.4 4.8-12.8 12.8-12.8 4.8 0 9.6 3.2 11.2 8l62.4 160 62.4-160c1.6-4.8 6.4-8 11.2-8 8 0 14.4 6.4 14.4 12.8 0 1.6-1.6 3.2-1.6 4.8z" fill="#FFFFFF" p-id="3540"></path><path d="M960 326.4v16H755.2s-100.8-20.8-97.6-108.8c0 0 3.2 92.8 96 92.8H960z" fill="#349C42" p-id="3541"></path><path d="M657.6 0v233.6c0 25.6 17.6 92.8 97.6 92.8H960L657.6 0z" fill="#FFFFFF" p-id="3542"></path></svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 5.2 KiB

View File

@@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1689494897388" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="958" xmlns:xlink="http://www.w3.org/1999/xlink" width="64" height="64"><path d="M146.56 0C101.76 0 66.56 35.2 66.56 80V940.8C66.56 985.6 101.76 1024 146.56 1024H879.36c44.8 0 80-35.2 80-80V323.2L658.56 0h-512z" fill="#F7622C" p-id="959"></path><path d="M962.56 326.4v16h-204.8s-99.2-19.2-99.2-108.8c0 0 3.2 92.8 96 92.8H962.56z" fill="#F54921" p-id="960"></path><path d="M658.56 0v233.6c0 25.6 16 92.8 96 92.8H962.56L658.56 0zM367.36 812.8H360.96l-121.6-54.4c-6.4-3.2-12.8-9.6-12.8-19.2 0-6.4 6.4-16 12.8-19.2L360.96 665.6h3.2c6.4 0 12.8 6.4 12.8 16 0 6.4-3.2 12.8-6.4 16L258.56 745.6 370.56 793.6c3.2 3.2 6.4 6.4 6.4 16 3.2 0-3.2 3.2-9.6 3.2zM501.76 636.8l-70.4 211.2c-3.2 6.4-6.4 9.6-12.8 9.6-9.6 0-16-6.4-16-16l3.2-3.2L476.16 627.2c3.2-6.4 6.4-12.8 12.8-12.8 9.6 0 12.8 6.4 12.8 16v6.4z m166.4 121.6l-121.6 54.4h-3.2c-6.4 0-16-3.2-16-12.8 0-6.4 3.2-12.8 6.4-16l112-48-112-48c-3.2-3.2-6.4-6.4-6.4-16 0-6.4 6.4-16 16-16h3.2l121.6 54.4c6.4 3.2 12.8 12.8 12.8 19.2-3.2 16-6.4 25.6-12.8 28.8z" fill="#FFFFFF" p-id="961"></path></svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1689494956529" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="3178" xmlns:xlink="http://www.w3.org/1999/xlink" width="64" height="64"><path d="M903.542857 256.8c6.857143 6.857143 10.742857 16.114286 10.742857 25.828571V987.428571c0 20.228571-16.342857 36.571429-36.571428 36.571429H146.285714c-20.228571 0-36.571429-16.342857-36.571428-36.571429V36.571429c0-20.228571 16.342857-36.571429 36.571428-36.571429h485.371429c9.714286 0 19.085714 3.885714 25.942857 10.742857l245.942857 246.057143zM829.942857 299.428571L614.857143 84.342857V299.428571h215.085714zM413.862857 613.634286l67.554286 151.965714a18.285714 18.285714 0 0 0 16.708571 10.857143h27.497143a18.285714 18.285714 0 0 0 16.72-10.868572l67.542857-152.4V793.142857a18.285714 18.285714 0 0 0 18.297143 18.285714H659.428571a18.285714 18.285714 0 0 0 18.285715-18.285714V482.285714a18.285714 18.285714 0 0 0-18.285715-18.285714h-39.714285a18.285714 18.285714 0 0 0-16.765715 10.994286L512.114286 683.657143l-90.834286-208.674286a18.285714 18.285714 0 0 0-16.765714-10.982857H364.571429a18.285714 18.285714 0 0 0-18.285715 18.285714v310.857143a18.285714 18.285714 0 0 0 18.285715 18.285714h31.005714a18.285714 18.285714 0 0 0 18.285714-18.285714V613.634286z" p-id="3179" data-spm-anchor-id="a313x.7781069.0.i3" class="selected" fill="#515151"></path></svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1689494925506" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="1120" xmlns:xlink="http://www.w3.org/1999/xlink" width="64" height="64"><path d="M149.76 0C104.96 0 66.56 35.2 66.56 80V940.8c0 48 38.4 83.2 83.2 83.2h732.8c44.8 0 80-35.2 80-80V323.2L658.56 0H149.76z" fill="#DD5154" p-id="1121"></path><path d="M962.56 326.4v16h-204.8s-99.2-19.2-96-105.6c0 0 3.2 89.6 96 89.6h204.8z" fill="#6B0D12" p-id="1122"></path><path d="M329.91232 652.3904l2.31424 0.02048c21.02272 0.33792 36.81792 5.3504 47.29856 15.15008 10.9056 10.19904 16.29184 26.112 16.29184 47.60064 0 41.71776-21.63712 63.2832-64.01536 63.90272l-1.90976 0.01536h-36.43904v63.45216l-0.03072 1.2544c-0.19968 3.59424-1.23392 6.5536-3.15904 8.8064-2.2784 2.65216-5.85216 3.90144-10.5472 3.90144-4.92544 0-8.63232-1.37728-10.9056-4.28032-1.85344-2.37056-2.87744-5.2224-3.08736-8.4992l-0.03584-1.24928v-173.78816l0.02048-1.28512c0.15872-5.4784 1.34656-9.3696 3.83488-11.61728 2.44736-2.21696 6.91712-3.24608 13.58336-3.36896l1.46432-0.01536h45.32224z m407.21408 0l1.0752 0.02048c8.66304 0.33792 13.47584 4.8384 13.47584 12.86144 0 4.57216-1.30048 7.98208-4.08064 9.96864-2.26304 1.61792-5.40672 2.45248-9.43616 2.60096l-1.37216 0.0256H659.3536v59.38688l69.74464 0.00512 1.17248 0.0256c6.43072 0.26112 10.69056 2.75456 12.00128 7.20896 1.28 2.80576 1.152 5.9392-0.128 8.82688-1.37216 5.7088-5.60128 8.8064-12.0576 9.10336l-1.03936 0.0256H659.3536v81.23904l-0.03584 1.13664c-0.2048 3.31776-1.28 6.0672-3.24608 8.1408-2.29376 2.42688-6.00064 3.52768-11.0336 3.52768-4.88448 0-8.448-1.1264-10.55744-3.6352-1.7408-2.06336-2.67776-4.75136-2.8672-8.00256l-0.03072-1.24416v-176.37888l0.02048-1.20832c0.16896-4.77184 1.3312-8.2688 3.69664-10.3936 2.28864-2.06848 5.88288-3.07712 10.78272-3.2256l1.24928-0.01536h89.79456z m-233.00096 0l2.65728 0.03072c13.3888 0.3072 25.0624 2.90816 35.00544 7.8336 10.57792 5.23776 19.34336 12.42112 26.27584 21.5296 6.89664 9.0624 12.0064 19.73248 15.33952 31.98976 3.31264 12.17024 4.9664 25.15456 4.9664 38.94784 0 13.98272-1.65376 27.06432-4.9664 39.23456-3.328 12.24704-8.38656 22.95296-15.17568 32.1024a72.28416 72.28416 0 0 1-25.85088 21.69344c-9.79968 4.95104-21.26336 7.55712-34.37056 7.84896l-2.47808 0.0256H451.59936l-1.14176-0.01024c-5.84704-0.11776-9.53856-1.09056-11.24352-3.51232-1.38752-1.96096-2.06336-4.92544-2.176-8.97536l-0.01536-1.24416v-173.78816l0.02048-1.25952c0.11264-4.01408 0.78336-6.9632 2.17088-8.92416 1.6896-2.39616 5.32992-3.38944 11.136-3.5072l1.27488-0.01536h52.50048z m-5.76512 24.33024h-33.85856v152.576h41.02656c17.3568 0 30.73536-6.5024 40.3712-19.59936 9.76896-13.27104 14.69952-32.53248 14.69952-57.83552 0-24.51456-5.06368-43.18208-15.08864-56.05888-9.56928-12.288-24.51968-18.6624-45.07648-19.06176l-2.0736-0.02048z m-168.46848 0.86016h-36.43904v76.88192h36.43904c14.08 0 23.92576-3.13344 29.67552-9.23136 5.79584-6.144 8.76544-16.04096 8.76544-29.78304 0-13.6704-3.29728-23.296-9.7536-29.056-6.22592-5.5552-15.13472-8.50944-26.81856-8.79104l-1.8688-0.02048zM658.56 0L962.56 326.4h-208c-80 0-96-64-96-92.8V0z" fill="#FFFFFF" p-id="1123"></path></svg>

After

Width:  |  Height:  |  Size: 3.2 KiB

View File

@@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1689495026020" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="958" xmlns:xlink="http://www.w3.org/1999/xlink" width="64" height="64"><path d="M146.56 0C104.96 0 66.56 35.2 66.56 80v864C66.56 988.8 101.76 1024 146.56 1024H879.36c44.8 0 80-35.2 80-80V323.2L658.56 0h-512z" fill="#99B7D2" p-id="959"></path><path d="M962.56 323.2v16h-204.8s-99.2-19.2-96-105.6c0 0 3.2 89.6 96 89.6h204.8z" fill="#527EA7" p-id="960"></path><path d="M449.07008 650.25024c3.00032 0.12288 5.84192 2.09408 8.72448 5.7344l0.7168 0.94208 47.79008 68.11136 45.7216-65.42848 0.64512-1.01376c2.82112-4.30592 5.89824-6.89664 9.33376-7.5776 3.56352-0.7168 7.1168 0.11264 10.54208 2.39616 6.32832 4.29568 7.2704 10.58304 2.944 17.8688l-0.5632 0.91136-52.87424 75.3664 62.83776 89.51808 0.65024 1.3824c1.07008 2.41152 1.7408 4.74624 2.01216 7.00416 0.41984 3.49184-1.56672 6.64064-5.55008 9.4464-7.39328 5.00736-14.1312 3.92192-19.03104-2.97984l-0.55296-0.8192L506.0096 770.6624l-56.43264 80.50688-0.73728 0.98816c-2.47296 3.13856-5.30432 5.04832-8.47872 5.59616-3.20512 0.55296-6.34368-0.24576-9.216-2.2272l-0.84992-0.62976c-3.16416-2.19136-4.85376-5.43744-4.9664-9.48224-0.1024-3.49184 0.8704-6.66112 2.7904-9.28768l0.67584-0.85504 61.19424-87.424-52.83328-75.58656-0.60416-0.8192c-1.67424-2.4576-2.39616-5.40672-2.19136-8.7552a11.42784 11.42784 0 0 1 5.43744-9.28768c3.2768-2.18624 6.36416-3.27168 9.2672-3.1488z m-62.98112 3.584l1.14688 0.03584c3.31264 0.21504 6.1696 1.31584 8.4736 3.30752 2.70336 2.33472 4.03968 5.67808 4.03968 9.82016 0 4.65408-1.58208 8.13568-4.82816 10.0864a17.16736 17.16736 0 0 1-7.74144 2.47296l-1.17248 0.03584h-43.60192v164.37248l-0.03072 1.30048c-0.17408 3.70688-1.08544 6.67136-2.82624 8.84224-2.10944 2.64192-5.7856 3.82464-10.88512 3.82464-5.12 0-8.81664-1.2544-10.92608-4.0192-1.6896-2.22208-2.60096-5.12-2.78016-8.6528l-0.03584-1.3568-0.00512-164.31104h-43.66336l-1.18784-0.03072c-3.39968-0.17408-6.2464-1.09056-8.46848-2.78528-2.73408-2.07872-4.0192-5.51424-4.0192-10.06592 0-4.36224 1.35168-7.75168 4.1472-9.9072 2.29376-1.77152 5.09952-2.74432 8.35072-2.93888l1.24416-0.03584h114.76992z m365.60896 0l1.14688 0.03584c3.31264 0.21504 6.1696 1.31584 8.4736 3.30752 2.70336 2.33472 4.03968 5.67808 4.03968 9.82016 0 4.65408-1.58208 8.13568-4.82816 10.0864a17.16736 17.16736 0 0 1-7.74144 2.47296l-1.17248 0.03584h-43.60192v164.37248l-0.03072 1.30048c-0.17408 3.70688-1.08544 6.67136-2.82624 8.84224-2.10944 2.64192-5.7856 3.82464-10.88512 3.82464-5.12 0-8.81664-1.2544-10.92608-4.0192-1.6896-2.22208-2.60096-5.12-2.78016-8.6528l-0.03584-1.3568v-164.31104h-43.66848l-1.18784-0.03072c-3.39968-0.17408-6.2464-1.09056-8.46848-2.78528-2.73408-2.07872-4.0192-5.51424-4.0192-10.06592 0-4.36224 1.35168-7.75168 4.1472-9.9072 2.29376-1.77152 5.09952-2.74432 8.35072-2.93888l1.24416-0.03584h114.76992zM658.56 0L962.56 323.2h-208c-80 0-96-64-96-92.8V0z" fill="#FFFFFF" p-id="961"></path></svg>

After

Width:  |  Height:  |  Size: 3.0 KiB

View File

@@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1692418843591" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4084" xmlns:xlink="http://www.w3.org/1999/xlink" width="64" height="64"><path d="M511.5 82c-236.6 0-429 192.4-429 429 0 236.5 192.5 429 429 429 236.6 0 429-192.4 429-429 0-236.5-192.4-429-429-429z m377.6 403.8H734.3c-4-139.9-41.4-259.9-97.5-331.9C776.5 203 879 332 889.1 485.8z m-402.8-349v349h-147c5.5-175.5 68.6-322.6 147-349z m0 399.4v349c-78.4-26.4-141.4-173.5-147-349h147z m50.5 349v-349h147c-5.6 175.5-68.6 322.6-147 349z m0-399.4v-349c78.4 26.4 141.4 173.5 147 349h-147zM386.3 153.9c-56.1 72-93.5 192-97.5 331.9H133.9C144.1 332 246.5 203 386.3 153.9zM133.9 536.2h154.8c4 139.9 41.4 259.9 97.5 331.9C246.5 819 144.1 690 133.9 536.2z m502.8 331.9c56.1-72 93.5-192 97.5-331.9H889C879 690 776.5 819 636.7 868.1z" fill="#5F9BEB" p-id="4085"></path></svg>

After

Width:  |  Height:  |  Size: 1006 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 428 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 596 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 223 KiB

View File

@@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1691391466028" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4715" xmlns:xlink="http://www.w3.org/1999/xlink" width="64" height="64"><path d="M511.957333 21.333333C241.024 21.333333 21.333333 240.981333 21.333333 512c0 216.832 140.544 400.725333 335.573334 465.664 24.490667 4.394667 32.256-10.069333 32.256-23.082667 0-11.690667 0.256-44.245333 0-85.205333-136.448 29.610667-164.736-64.64-164.736-64.64-22.314667-56.704-54.4-71.765333-54.4-71.765333-44.586667-30.464 3.285333-29.824 3.285333-29.824 49.194667 3.413333 75.178667 50.517333 75.178667 50.517333 43.776 75.008 114.816 53.333333 142.762666 40.789333 4.522667-31.658667 17.152-53.376 31.189334-65.536-108.970667-12.458667-223.488-54.485333-223.488-242.602666 0-53.546667 19.114667-97.322667 50.517333-131.669334-5.034667-12.330667-21.930667-62.293333 4.778667-129.834666 0 0 41.258667-13.184 134.912 50.346666a469.802667 469.802667 0 0 1 122.88-16.554666c41.642667 0.213333 83.626667 5.632 122.88 16.554666 93.653333-63.488 134.784-50.346667 134.784-50.346666 26.752 67.541333 9.898667 117.504 4.864 129.834666 31.402667 34.346667 50.474667 78.122667 50.474666 131.669334 0 188.586667-114.730667 230.016-224.042666 242.090666 17.578667 15.232 33.578667 44.672 33.578666 90.453334v135.850666c0 13.141333 7.936 27.605333 32.853334 22.869334C862.250667 912.597333 1002.666667 728.746667 1002.666667 512 1002.666667 240.981333 783.018667 21.333333 511.957333 21.333333z" p-id="4716"></path></svg>

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

@@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1688889092975" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2652" xmlns:xlink="http://www.w3.org/1999/xlink" width="64" height="64"><path d="M932.15857778 820.62601482V639.06702222c-26.82121482 23.42305185-57.04059259 42.71976297-89.4445037 57.28331853-104.97896297 46.11792592-218.45333333 69.41961482-333.14133333 68.32734814-148.06281482 8.61677037-294.66927408-32.768-416.39632593-117.35798519v182.89398519C101.4290963 910.07051852 277.52675555 997.45185185 512.36408889 997.45185185c234.83733333 0 409.6-88.10951111 419.79448889-168.57315555v-8.25268148z" p-id="2653" fill="#4e83fd"></path><path d="M932.15857778 505.93185185v-3.39816296 8.25268148c-10.19448889 80.58500741-184.95715555 168.57315555-419.79448889 168.57315555-234.83733333 0-410.93499259-87.38133333-419.18767407-167.23816295V329.10601482C214.90346667 413.81736297 361.50992592 455.08077037 509.57274075 446.464c114.688 1.09226667 228.16237037-22.08805925 333.14133333-68.32734815 32.40391111-14.68491852 62.62328889-33.98162963 89.4445037-57.28331852V505.93185185z" p-id="2654" fill="#4e83fd"></path><path d="M816.13558518 85.40918518c69.66234075 30.70482963 111.28983703 74.3954963 111.28983704 113.35300741 0 38.22933333-42.96248889 80.58500741-111.28983704 113.35300741-97.09037037 41.26340741-201.70524445 61.53102222-307.16965926 59.34648889-238.96367408 0-417.1245037-90.7794963-417.1245037-171.97131852s178.88900741-172.6994963 418.4594963-172.69949629c104.97896297-2.3058963 209.10838518 17.71899259 305.83466666 58.6183111z" p-id="2655" fill="#4e83fd"></path></svg>

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

@@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1691459708057" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5077" xmlns:xlink="http://www.w3.org/1999/xlink" width="64" height="64"><path d="M934.423357 388.738675H636.152113v99.05297h-64.657602L413.227927 382.546649v-64.511269h32.679284c69.808926 0 126.410038-56.601112 126.410038-126.410038 0-69.807902-56.602136-126.409015-126.410038-126.409015H330.962296c-69.808926 0-126.410038 56.602136-126.410038 126.409015 0 69.809949 56.602136 126.410038 126.410038 126.410038h32.702819v64.536852L166.551782 513.623987l197.114356 131.054825v61.440327h-32.702819c-69.808926 0-126.410038 56.601112-126.410038 126.410038 0 69.807902 56.602136 126.410038 126.410038 126.410038h114.944915c60.205197 0 110.372783-42.185798 123.096573-98.54541h240.532215V636.430964h124.887358V388.738675zM759.973186 810.856575h-189.833533c-10.328229-59.431577-61.84965-104.737436-124.232442-104.737436h-32.679284v-61.414745l161.435763-107.349936h61.488423v99.075483h123.821073v174.426634z" p-id="5078" fill="#FC9663"></path></svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

@@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1691460113549" class="icon" viewBox="0 0 1443 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2328" xmlns:xlink="http://www.w3.org/1999/xlink" width="90.1875" height="64"><path d="M1200.165345 1023.218368H349.208974c-192.401638 0-349.208974-215.369584-349.208974-406.207959a348.006463 348.006463 0 0 1 349.208974-346.022321 322.33287 322.33287 0 0 1 38.780955 2.344895C470.963136 141.056856 617.248506 0.002405 774.777348 0.002405a454.368494 454.368494 0 0 1 454.669122 423.403856c120.251024 14.309872 213.625944 168.952689 213.625944 359.189808a242.005186 242.005186 0 0 1-242.907069 240.622299zM349.148848 330.57247A288.061328 288.061328 0 0 0 60.125512 617.010409c0 158.009846 129.690729 346.623577 289.083462 346.623577h850.956371A182.120176 182.120176 0 0 0 1382.886776 782.596069c0-156.867461-81.951073-301.349066-182.661305-301.349066a30.062756 30.062756 0 0 1-30.062756-30.062756A394.062606 394.062606 0 0 0 774.717222 59.28616c-142.67784 0-274.893841 136.965916-344.940062 260.70422a29.581752 29.581752 0 0 1-31.265266 14.73075 297.080155 297.080155 0 0 0-49.30292-4.14866z m881.079253 120.912405zM300.62756 783.497952H240.502048v-240.502048h60.125512v60.125512h60.125512v-60.125512h60.125512v240.502048H360.753072v-120.251024H300.62756v120.251024z m180.376536-180.376536v-60.125512h180.376536v60.125512h-60.125512v180.376536H541.129608v-180.376536H481.004096z m240.502048 0v-60.125512h180.376536v60.125512h-60.125512v180.376536h-60.125512v-180.376536h-60.125512z m300.62756 180.376536h-60.125512v-240.502048h60.125512c71.368983-0.962008 127.225583-24.050205 126.263575 30.062756-1.863891 50.264928-7.936568 147.548006-66.138063 150.31378h-60.125512v60.125512z m0-180.376536v60.125512a35.293676 35.293676 0 0 0 12.025103 6.012551q56.39773 5.471422 54.954717-36.075307 0-37.818947-54.954717-36.075307a35.293676 35.293676 0 0 0-12.025103 6.012551z" fill="#7839ee" p-id="2329"></path></svg>

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

@@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1686561811905" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="2855" xmlns:xlink="http://www.w3.org/1999/xlink" ><path d="M992 528c0 273.9-222.1 496-496 496S0 801.9 0 528 222.1 32 496 32c86.2 0 167.3 22 238 60.7 2.3 1.3 2.8 4.4 0.9 6.3l-37 37.3-4.2 4.3c-1.2 1.2-3.1 1.5-4.6 0.8-8.2-4.1-16.5-7.9-24.9-11.5C610.9 107.4 554.3 96 496 96s-114.9 11.4-168.1 33.9c-51.4 21.8-97.7 52.9-137.3 92.6-39.7 39.7-70.9 85.9-92.6 137.3C75.4 413.1 64 469.6 64 528c0 58.3 11.4 114.9 33.9 168.1 21.8 51.4 52.9 97.6 92.6 137.3 39.7 39.7 85.9 70.9 137.3 92.6 53.3 22.6 109.9 34 168.2 34s114.9-11.4 168.1-33.9c51.4-21.8 97.7-52.9 137.3-92.6 39.7-39.7 70.9-85.9 92.6-137.3 22.6-53.3 34-109.9 34-168.2 0-58.4-11.4-114.9-33.9-168.1-3.6-8.5-7.4-16.8-11.5-25-0.8-1.5-0.5-3.4 0.8-4.6l4.3-4.2 37.3-37c1.9-1.9 5-1.4 6.3 0.9C970 360.6 992 441.7 992 528z" p-id="2856" fill="#6CD3CC"></path><path d="M781.4 397c-3.7-8-11.7-13.1-20.6-13.1H740c-6 0-11.8 2.4-16 6.6-7 7-8.6 17.6-4.1 26.4 2.6 5.1 5 10.3 7.3 15.7 13.2 31.2 19.9 64.3 19.9 98.5s-6.7 67.3-19.9 98.5c-12.7 30.1-31 57.2-54.2 80.4-23.3 23.3-50.3 41.5-80.4 54.2-31.3 13.1-64.4 19.8-98.6 19.8s-67.3-6.7-98.5-19.9c-30.1-12.7-57.2-31-80.4-54.2-23.3-23.3-41.5-50.3-54.2-80.4-13.2-31.2-19.9-64.3-19.9-98.5s6.7-67.3 19.9-98.5c12.7-30.1 31-57.2 54.2-80.4 23.3-23.3 50.3-41.5 80.4-54.2 31.2-13.2 64.3-19.9 98.5-19.9s67.3 6.7 98.5 19.9c4.9 2.1 9.8 4.3 14.6 6.7 8.8 4.4 19.4 2.6 26.3-4.4 4.3-4.3 6.7-10.1 6.7-16.2v-20.2c0-9-5.2-17.1-13.4-20.8-40.4-18.6-85.3-29-132.6-29-175.5 0-318 143.4-317 318.9C178 707.1 319.6 848 494 848c174.8 0 316.6-141.3 317-316.2 0.1-48.2-10.5-93.9-29.6-134.8z" p-id="2857" fill="#6CD3CC"></path><path d="M634.5 488.5c-0.8-2.9-4.5-3.9-6.7-1.7l-34.7 34.7-1.8 1.8c-9 9-15.7 20.1-20.1 32.1-11.5 31.6-42.4 54-78.3 52.7-41.6-1.6-75.3-35.3-76.9-76.9-1.4-35.9 21-66.8 52.7-78.3 12-4.4 23-11.1 32.1-20.1l1.8-1.8 34.7-34.7c2.2-2.2 1.2-5.8-1.7-6.7-12.9-3.7-26.5-5.6-40.6-5.5-79.4 0.5-143 64.5-143 143.9 0 79.5 64.5 144 144 144 79.4 0 143.4-63.6 144-142.9 0.1-14.1-1.8-27.8-5.5-40.6z" p-id="2858" fill="#6CD3CC"></path><path d="M1014.3 146H882c-2.2 0-4-1.8-4-4V9.8c0-2.4-2-4-4-4-1 0-2 0.4-2.8 1.2L766.8 112.4l-46.1 46.5-44 44.4c-3 3-4.6 7-4.6 11.3v85.5c0 4.3-1.7 8.3-4.7 11.3l-94.7 94.7-47.4 47.4-51.8 51.9c-12.5 12.5-12.5 32.8 0 45.3 6.3 6.3 14.4 9.4 22.6 9.4s16.4-3.1 22.6-9.4l51.8-51.9 123.2-123.2 19-19c3-3 7.1-4.7 11.3-4.7h85.5c4.2 0 8.3-1.7 11.3-4.6l44.3-43.9 46.5-46.1L1017 152.9c2.6-2.6 0.8-6.9-2.7-6.9zM864 214.3l-44 43.5-25.6 25.4c-3 3-7 4.6-11.3 4.6H744c-4.4 0-8-3.6-8-8v-39c0-4.2 1.7-8.3 4.6-11.3l25.5-25.7 43.5-43.9 1.6-1.6c1.6-1.7 4.5-0.7 4.8 1.6 4.8 25.8 23.5 41.6 48.6 47.7 2.1 0.5 2.9 3.2 1.3 4.7l-1.9 2z" p-id="2859" fill="#6CD3CC"></path></svg>

After

Width:  |  Height:  |  Size: 2.8 KiB

View File

@@ -0,0 +1 @@
<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1691460052375" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="7219" xmlns:xlink="http://www.w3.org/1999/xlink" width="64" height="64"><path d="M950.676002 419.057175a255.346807 255.346807 0 0 0-22.014863-209.48251 257.949339 257.949339 0 0 0-277.74565-123.72694A258.759964 258.759964 0 0 0 212.538139 178.386943a255.346807 255.346807 0 0 0-170.572521 123.726941 257.949339 257.949339 0 0 0 31.699696 302.789689 255.133485 255.133485 0 0 0 21.758876 209.525175 258.162662 258.162662 0 0 0 277.958972 123.726941A255.346807 255.346807 0 0 0 565.757223 1023.996587a258.375984 258.375984 0 0 0 246.259276-179.446729 255.560129 255.560129 0 0 0 170.529856-123.726941 258.375984 258.375984 0 0 0-31.870353-301.765742zM565.757223 957.013381a190.966133 190.966133 0 0 1-122.702994-44.371041l6.015689-3.455821 203.893466-117.668587a33.918248 33.918248 0 0 0 16.724469-29.054499v-287.430483l86.182214 49.832092a3.029177 3.029177 0 0 1 1.621249 2.218552v238.195693a192.160738 192.160738 0 0 1-191.734093 191.734094zM153.618516 780.979809a190.710147 190.710147 0 0 1-22.825487-128.590689l6.058354 3.626479 204.064123 117.711252a32.8943 32.8943 0 0 0 33.278281 0l249.288453-143.736574v99.493526a3.413157 3.413157 0 0 1-1.407927 2.645197L415.578315 851.205514a191.990081 191.990081 0 0 1-261.959799-70.225705zM99.861294 336.928085a191.350114 191.350114 0 0 1 100.944118-84.176984V494.957254a32.680978 32.680978 0 0 0 16.553811 28.841176l248.093849 143.139272-86.182214 49.832092a3.242499 3.242499 0 0 1-3.029177 0l-206.069353-118.863193A192.160738 192.160738 0 0 1 99.861294 335.904138z m708.102081 164.471503l-248.861809-144.504534L645.070458 307.23362a3.242499 3.242499 0 0 1 3.029177 0l206.069353 119.076514a191.734094 191.734094 0 0 1-28.841177 345.795467v-242.248817a33.704925 33.704925 0 0 0-17.364436-28.457196z m85.75557-128.97467l-6.01569-3.626479-203.680143-118.692534a33.107623 33.107623 0 0 0-33.491603 0L401.456378 393.842478V294.306288a2.815855 2.815855 0 0 1 1.194605-2.602533l206.069353-118.905856a191.990081 191.990081 0 0 1 284.998609 198.816394z m-539.278804 176.417552l-86.182214-49.661434a3.413157 3.413157 0 0 1-1.62125-2.431875V259.236099a191.990081 191.990081 0 0 1 314.65041-147.320388l-6.058354 3.413157-203.850801 117.668587a33.918248 33.918248 0 0 0-16.767134 29.054499z m46.802915-100.901454l111.012931-63.996693 111.226253 63.996693v127.950723l-110.799609 63.996693-111.226253-63.996693z" p-id="7220"></path></svg>

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 177 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 455 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 149 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 97 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 776 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 572 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.9 KiB

View File

@@ -0,0 +1,89 @@
async function embedChatbot() {
const chatBtnId = 'fastgpt-chatbot-button';
const chatWindowId = 'fastgpt-chatbot-window';
const script = document.getElementById('fastgpt-iframe');
const botSrc = script?.getAttribute('data-src');
const primaryColor = script?.getAttribute('data-color') || '#4e83fd';
if (!botSrc) {
console.error(`Can't find appid`);
return;
}
if (document.getElementById(chatBtnId)) {
return;
}
const MessageIcon = `<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1690532785664" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="4132" xmlns:xlink="http://www.w3.org/1999/xlink" ><path d="M512 32C247.04 32 32 224 32 464A410.24 410.24 0 0 0 172.48 768L160 965.12a25.28 25.28 0 0 0 39.04 22.4l168-112A528.64 528.64 0 0 0 512 896c264.96 0 480-192 480-432S776.96 32 512 32z m244.8 416l-361.6 301.76a12.48 12.48 0 0 1-19.84-12.48l59.2-233.92h-160a12.48 12.48 0 0 1-7.36-23.36l361.6-301.76a12.48 12.48 0 0 1 19.84 12.48l-59.2 233.92h160a12.48 12.48 0 0 1 8 22.08z" fill=${primaryColor} p-id="4133"></path></svg>`;
const CloseIcon = `<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1690535441526" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="6367" xmlns:xlink="http://www.w3.org/1999/xlink"><path d="M512 1024A512 512 0 1 1 512 0a512 512 0 0 1 0 1024zM305.956571 370.395429L447.488 512 305.956571 653.604571a45.568 45.568 0 1 0 64.438858 64.438858L512 576.512l141.604571 141.531429a45.568 45.568 0 0 0 64.438858-64.438858L576.512 512l141.531429-141.604571a45.568 45.568 0 1 0-64.438858-64.438858L512 447.488 370.395429 305.956571a45.568 45.568 0 0 0-64.438858 64.438858z" fill=${primaryColor} p-id="6368"></path></svg>`;
const ChatBtn = document.createElement('div');
ChatBtn.id = chatBtnId;
ChatBtn.style.cssText =
'position: fixed; bottom: 1rem; right: 1rem; width: 40px; height: 40px; cursor: pointer; z-index: 2147483647; transition: 0;';
const ChatBtnDiv = document.createElement('div');
ChatBtnDiv.innerHTML = MessageIcon;
const iframe = document.createElement('iframe');
iframe.allow = 'fullscreen;microphone';
iframe.title = 'FastGpt Chat Window';
iframe.id = chatWindowId;
iframe.src = botSrc;
iframe.style.cssText =
'visibility: hidden; border: none; position: fixed; flex-direction: column; justify-content: space-between; box-shadow: rgba(150, 150, 150, 0.2) 0px 10px 30px 0px, rgba(150, 150, 150, 0.2) 0px 0px 0px 1px; bottom: 4rem; right: 1rem; width: 24rem; height: 40rem; max-width: 90vw; max-height: 85vh; border-radius: 0.75rem; display: flex; z-index: 2147483647; overflow: hidden; left: unset; background-color: #F3F4F6;';
document.body.appendChild(iframe);
let chatBtnDragged = false;
let chatBtnDown = false;
let chatBtnMouseX;
let chatBtnMouseY;
ChatBtn.addEventListener('click', function () {
if (chatBtnDragged) {
chatBtnDragged = false;
return;
}
const chatWindow = document.getElementById(chatWindowId);
if (!chatWindow) return;
const visibilityVal = chatWindow.style.visibility;
if (visibilityVal === 'hidden') {
chatWindow.style.visibility = 'unset';
ChatBtnDiv.innerHTML = CloseIcon;
} else {
chatWindow.style.visibility = 'hidden';
ChatBtnDiv.innerHTML = MessageIcon;
}
});
ChatBtn.addEventListener('mousedown', (e) => {
if (!chatBtnMouseX && !chatBtnMouseY) {
chatBtnMouseX = e.clientX;
chatBtnMouseY = e.clientY;
}
chatBtnDown = true;
});
ChatBtn.addEventListener('mousemove', (e) => {
if (!chatBtnDown) return;
chatBtnDragged = true;
const transformX = e.clientX - chatBtnMouseX;
const transformY = e.clientY - chatBtnMouseY;
ChatBtn.style.transform = `translate3d(${transformX}px, ${transformY}px, 0)`;
e.stopPropagation();
});
ChatBtn.addEventListener('mouseup', (e) => {
chatBtnDown = false;
});
ChatBtn.addEventListener('mouseleave', (e) => {
chatBtnDown = false;
});
ChatBtn.appendChild(ChatBtnDiv);
document.body.appendChild(ChatBtn);
}
document.body.onload = embedChatbot;

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,172 @@
{
"App": "App",
"Cancel": "No",
"Confirm": "Yes",
"Running": "Running",
"Warning": "Warning",
"UnKnow": "UnKnow",
"app": {
"Advance App TestTip": "The current application is advanced editing mode \n. If you need to switch to [simple mode], please click the save button on the left",
"App Detail": "App Detail",
"Chat Logs Tips": "Logs record the app's online, shared, and API conversations",
"Chat logs": "Chat Logs",
"Confirm Del App Tip": "Confirm to delete the app and all its chats",
"Confirm Save App Tip": "The application may be in advanced orchestration mode, and the advanced orchestration configuration will be overwritten after saving, please confirm!",
"Connection is invalid": "Connecting is invalid",
"Connection type is different": "Connection type is different",
"Copy Module Config": "Copy config",
"Export Config Successful": "The configuration has been copied. Please check for important data",
"Export Configs": "Export Configs",
"Import Config": "Import Config",
"Import Config Failed": "Failed to import the configuration, please ensure that the configuration is normal!",
"Import Configs": "Import Configs",
"Input Field Settings": "Input Field Settings",
"Logs Empty": "Logs is empty",
"Logs Message Total": "Message Count",
"Logs Source": "Source",
"Logs Time": "Time",
"Logs Title": "Title",
"My Apps": "My Apps",
"Output Field Settings": "Output Field Settings",
"Paste Config": "Paste Config"
},
"chat": {
"Complete Response": "Complete Response",
"Confirm to clear history": "Confirm to clear history?",
"Exit Chat": "Exit",
"History": "History",
"New Chat": "New Chat",
"You need to a chat app": "You need to a chat app",
"logs": {
"api": "API",
"online": "Online Chat",
"share": "Share",
"test": "Test Chat "
}
},
"commom": {
"Password inconsistency": "Password inconsistency"
},
"common": {
"Add": "Add",
"Cancel": "Cancel",
"Collect": "Collect",
"Copy": "Copy",
"Copy Successful": "Copy Successful",
"Course": "",
"Delete": "Delete",
"Filed is repeat": "Filed is repeated",
"Filed is repeated": "",
"Input": "Input",
"Output": "Output",
"export": ""
},
"dataset": {
"Confirm to delete the data": "Confirm to delete the data?",
"Queue Desc": "This data refers to the current amount of training for the entire system. FastGPT uses queued training, and if you have too much data to train, you may need to wait for a while",
"System Data Queue": "Data Queue"
},
"file": {
"Click to download CSV template": "Click to download CSV template",
"Create File": "Create File",
"Create file": "Create file",
"Drag and drop": "Drag and drop files here",
"Fetch Url": "Fetch Url",
"If the imported file is garbled, please convert CSV to UTF-8 encoding format": "If the imported file is garbled, please convert CSV to UTF-8 encoding format",
"Release the mouse to upload the file": "Release the mouse to upload the file",
"Select a maximum of 10 files": "Select a maximum of 10 files",
"max 10": "Max 10 files",
"select a document": "select a document",
"support": "support {{fileExtension}} file",
"upload error description": "Only upload multiple files or one folder at a time"
},
"home": {
"AI Assistant": "AI Assistant",
"AI Assistant Desc": "",
"Advanced Settings": "",
"Advanced Settings Desc": "",
"Choice Debug": "Convenient Debugging",
"Choice Debug Desc": "Search testing, reference modification, full conversation preview and many other debugging ways",
"Choice Desc": "FastGPT follows the Apache License 2.0 open source protocol",
"Choice Extension": "Infinite Extension",
"Choice Extension Desc": "HTTP based extension, easy to achieve custom functions",
"Choice Models": "Multiple Models",
"Choice Models Desc": "",
"Choice Open": "Open",
"Choice Open Desc": "",
"Choice QA": "QA Struceture",
"Choice QA Desc": "The index is constructed with the structure of QA pairs, and ADAPTS to various scenarios such as Q&A and reading",
"Choice Visual": "Visual workflow",
"Choice Visual Desc": "Visualize modular operations, easily implement complex workflows, and make your AI no longer monolithic",
"Community": "Community",
"Dateset": "",
"Dateset Desc": "",
"Docs": "Docs",
"FastGPT Ability": "FastGPT Ability",
"FastGPT Desc": "FastGPT is a knowledgebase question answering system based on LLM large language model, which provides out-of-the-box data processing, model invocation and other capabilities. At the same time, workflow orchestration can be performed through Flow visualization to achieve complex Q&A scenarios!",
"Features": "Features",
"Footer Developer": "Developer",
"Footer Docs": "Docs",
"Footer FastGPT Cloud": "FastGPT Cloud",
"Footer Feedback": "Feedback",
"Footer Git": "Code",
"Footer Product": "Product",
"Footer Support": "Support",
"Login": "Login",
"Open": "",
"OpenAPI": "OpenAPI",
"OpenAPI Desc": "",
"Quickly build AI question and answer library": "Quickly build AI question and answer library",
"Start Now": "Start Now",
"Visual AI orchestration": "Visual AI orchestration",
"Why FastGPT": "",
"desc": "",
"slogan": ""
},
"navbar": {
"Account": "Account",
"Apps": "Apps",
"Chat": "Chat",
"Datasets": "DataSets",
"Store": "Store",
"Tools": "Tools"
},
"user": {
"Account": "Account",
"Amount of earnings": "Earnings",
"Amount of inviter": "Inviter",
"Application Name": "Application Name",
"Avatar": "Avatar",
"Balance": "Balance",
"Bill Detail": "Bill Detail",
"Change": "Change",
"Copy invite url": "Copy invitation link",
"Invite Url": "Invite Url",
"Invite url tip": "Friends who register through this link will be permanently bound to you, and you will get a certain balance reward when they recharge. In addition, when friends register with their mobile phone number, you will get 5 yuan reward immediately.",
"Notice": "Notice",
"Old password is error": "Old password is error",
"OpenAI Account Setting": "OpenAI Account Setting",
"Password": "Password",
"Pay": "Pay",
"Personal Information": "Personal",
"Promotion": "Promotion",
"Promotion Rate": "Promotion Rate",
"Promotion Record": "Promotion",
"Promotion rate tip": "You will be rewarded with a percentage of the balance when your friends top up",
"Recharge Record": "Recharge",
"Replace": "Replace",
"Set OpenAI Account Failed": "Set OpenAI account failed",
"Sign Out": "Sign Out",
"Source": "Source",
"Time": "Time",
"Total Amount": "Total Amount",
"Update Password": "Update Password",
"Update password failed": "Update password failed",
"Update password succseful": "Update password succseful",
"Usage Record": "Usage",
"promotion": {
"pay": "",
"register": ""
}
}
}

View File

@@ -0,0 +1,172 @@
{
"App": "应用",
"Cancel": "取消",
"Confirm": "确认",
"Running": "运行中",
"Warning": "提示",
"UnKnow": "未知",
"app": {
"Advance App TestTip": "当前应用为高级编排模式\n如需切换为【简易模式】请点击左侧保存按键",
"App Detail": "应用详情",
"Chat Logs Tips": "日志会记录该应用的在线、分享和 API 对话记录",
"Chat logs": "对话日志",
"Confirm Del App Tip": "确认删除该应用及其所有聊天记录?",
"Confirm Save App Tip": "该应用可能为高级编排模式,保存后将会覆盖高级编排配置,请确认!",
"Connection is invalid": "连接无效",
"Connection type is different": "连接的类型不一致",
"Copy Module Config": "复制配置",
"Export Config Successful": "已复制配置,请注意检查是否有重要数据",
"Export Configs": "导出配置",
"Import Config": "导入配置",
"Import Config Failed": "导入配置失败,请确保配置正常!",
"Import Configs": "导入配置",
"Input Field Settings": "输入字段编辑",
"Logs Empty": "还没有日志噢~",
"Logs Message Total": "消息总数",
"Logs Source": "来源",
"Logs Time": "时间",
"Logs Title": "标题",
"My Apps": "我的应用",
"Output Field Settings": "输出字段编辑",
"Paste Config": "粘贴配置"
},
"chat": {
"Complete Response": "完整响应",
"Confirm to clear history": "确认清空该应用的聊天记录?",
"Exit Chat": "退出聊天",
"History": "记录",
"New Chat": "新对话",
"You need to a chat app": "你需要创建一个应用",
"logs": {
"api": "API 调用",
"online": "在线使用",
"share": "外部链接调用",
"test": "测试"
}
},
"commom": {
"Password inconsistency": "两次密码不一致"
},
"common": {
"Add": "添加",
"Cancel": "取消",
"Collect": "收藏",
"Copy": "复制",
"Copy Successful": "复制成功",
"Course": "",
"Delete": "删除",
"Filed is repeat": "",
"Filed is repeated": "字段重复了",
"Input": "输入",
"Output": "输出",
"export": ""
},
"dataset": {
"Confirm to delete the data": "确认删除该数据?",
"Queue Desc": "该数据是指整个系统当前待训练的数量。FastGPT 采用排队训练的方式,如果待训练的数据过多,可能需要等待一段时间",
"System Data Queue": "排队长度"
},
"file": {
"Click to download CSV template": "点击下载 CSV 模板",
"Create File": "创建新文件",
"Create file": "创建文件",
"Drag and drop": "拖拽文件至此",
"Fetch Url": "链接读取",
"If the imported file is garbled, please convert CSV to UTF-8 encoding format": "如果导入文件乱码,请将 CSV 转成 UTF-8 编码格式",
"Release the mouse to upload the file": "松开鼠标上传文件",
"Select a maximum of 10 files": "最多选择10个文件",
"max 10": "最多选择 10 个文件",
"select a document": "选择文件",
"support": "支持 {{fileExtension}} 文件",
"upload error description": "单次只支持上传多个文件或者一个文件夹"
},
"home": {
"AI Assistant": "AI 客服",
"AI Assistant Desc": "无论对内还是对外AI 将 24 小时为您的用户提供服务",
"Advanced Settings": "高级编排",
"Advanced Settings Desc": "基于 Flow 的流程编排模式,让你的 AI 轻松实现数据库查询、IO 操作、联网通信等扩展能力",
"Choice Debug": "调试便捷",
"Choice Debug Desc": "拥有搜索测试、引用修改、完整对话预览等多种调试途径",
"Choice Desc": "",
"Choice Extension": "无限扩展",
"Choice Extension Desc": "基于 HTTP 实现扩展,轻松实现定制功能",
"Choice Models": "支持多种模型",
"Choice Models Desc": "支持 GPT、Claude、文心一言等多模型",
"Choice Open": "更开放",
"Choice Open Desc": "FastGPT 遵循 Apache License 2.0 开源协议",
"Choice QA": "独特的 QA 结构",
"Choice QA Desc": "采用 QA 对的结构构建索引,适应问答、阅读等多种场景",
"Choice Visual": "可视化工作流",
"Choice Visual Desc": "可视化模块操作,轻松实现复杂工作流,让你的 AI 不再单一",
"Community": "社区",
"Dateset": "自动数据预处理",
"Dateset Desc": "提供手动输入、直接分段、LLM 自动处理和 CSV 等多种数据导入途径",
"Docs": "文档",
"FastGPT Ability": "FastGPT 能力",
"FastGPT Desc": "FastGPT 是一个基于 LLM 大语言模型的知识库问答系统,提供开箱即用的数据处理、模型调用等能力。同时可以通过 Flow 可视化进行工作流编排,从而实现复杂的问答场景!",
"Features": "特点",
"Footer Developer": "开发者",
"Footer Docs": "文档",
"Footer FastGPT Cloud": "FastGPT 线上服务",
"Footer Feedback": "反馈",
"Footer Git": "源码",
"Footer Product": "产品",
"Footer Support": "支持",
"Login": "登录",
"Open": "",
"OpenAPI": "OpenAPI",
"OpenAPI Desc": "与 GPT API 一致的对外接口,助你轻松接入已有应用",
"Quickly build AI question and answer library": "快速搭建 AI 问答系统",
"Start Now": "立即开始",
"Visual AI orchestration": "可视化 AI 编排",
"Why FastGPT": "为什么选择 FastGPT",
"desc": "基于 LLM 大模型的 AI 知识库问答平台",
"slogan": "让 AI 更懂你的知识"
},
"navbar": {
"Account": "账号",
"Apps": "应用",
"Chat": "聊天",
"Datasets": "知识库",
"Store": "应用市场",
"Tools": "工具"
},
"user": {
"Account": "账号",
"Amount of earnings": "收益(¥)",
"Amount of inviter": "累计邀请人数",
"Application Name": "应用名",
"Avatar": "头像",
"Balance": "余额",
"Bill Detail": "账单详情",
"Change": "变更",
"Copy invite url": "复制邀请链接",
"Invite Url": "邀请链接",
"Invite url tip": "通过该链接注册的好友将永久与你绑定,其充值时你会获得一定余额奖励。\n此外好友使用手机号注册时你将立即获得 5 元奖励。",
"Notice": "通知",
"Old password is error": "旧密码错误",
"OpenAI Account Setting": "OpenAI 账号配置",
"Password": "密码",
"Pay": "充值",
"Personal Information": "个人信息",
"Promotion": "",
"Promotion Rate": "返现比例",
"Promotion Record": "推广记录",
"Promotion rate tip": "好友充值时你将获得一定比例的余额奖励",
"Recharge Record": "充值记录",
"Replace": "更换",
"Set OpenAI Account Failed": "设置 OpenAI 账号异常",
"Sign Out": "登出",
"Source": "来源",
"Time": "时间",
"Total Amount": "总金额",
"Update Password": "修改密码",
"Update password failed": "修改密码异常",
"Update password succseful": "修改密码成功",
"Usage Record": "使用记录",
"promotion": {
"pay": "好友充值",
"register": "好友注册"
}
}
}

56
client/src/api/app.ts Normal file
View File

@@ -0,0 +1,56 @@
import { GET, POST, DELETE, PUT } from './request';
import type { AppSchema } from '@/types/mongoSchema';
import type { AppListItemType, AppUpdateParams } from '@/types/app';
import { RequestPaging } from '../types/index';
import type { Props as CreateAppProps } from '@/pages/api/app/create';
import { addDays } from 'date-fns';
/**
* 获取模型列表
*/
export const getMyModels = () => GET<AppListItemType[]>('/app/myApps');
/**
* 创建一个模型
*/
export const postCreateApp = (data: CreateAppProps) => POST<string>('/app/create', data);
/**
* 根据 ID 删除模型
*/
export const delModelById = (id: string) => DELETE(`/app/del?appId=${id}`);
/**
* 根据 ID 获取模型
*/
export const getModelById = (id: string) => GET<AppSchema>(`/app/detail?appId=${id}`);
/**
* 根据 ID 更新模型
*/
export const putAppById = (id: string, data: AppUpdateParams) =>
PUT(`/app/update?appId=${id}`, data);
/* 共享市场 */
/**
* 获取共享市场模型
*/
export const getShareModelList = (data: { searchText?: string } & RequestPaging) =>
POST(`/app/share/getModels`, data);
/**
* 收藏/取消收藏模型
*/
export const triggerModelCollection = (appId: string) =>
POST<number>(`/app/share/collection?appId=${appId}`);
// ====================== data
export const getAppTotalUsage = (data: { appId: string }) =>
POST<{ date: String; total: number }[]>(`/app/data/totalUsage`, {
...data,
start: addDays(new Date(), -13),
end: addDays(new Date(), 1)
}).then((res) => (res.length === 0 ? [{ date: new Date(), total: 0 }] : res));
export const getAppChatLogs = (data: RequestPaging & { appId: string }) =>
POST(`/chat/getChatLogs`, data);

View File

@@ -1,50 +1,37 @@
import { GET, POST, DELETE, PUT } from './request';
import type { HistoryItemType } from '@/types/chat';
import type { ChatHistoryItemType } from '@/types/chat';
import type { InitChatResponse, InitShareChatResponse } from './response/chat';
import { RequestPaging } from '../types/index';
import type { ShareChatSchema } from '@/types/mongoSchema';
import type { ShareChatEditType } from '@/types/model';
import { Obj2Query } from '@/utils/tools';
import type { QuoteItemType } from '@/pages/api/openapi/kb/appKbSearch';
import type { OutLinkSchema } from '@/types/mongoSchema';
import type { ShareChatEditType } from '@/types/app';
import type { Props as UpdateHistoryProps } from '@/pages/api/chat/history/updateChatHistory';
/**
* 获取初始化聊天内容
*/
export const getInitChatSiteInfo = (modelId: '' | string, chatId: '' | string) =>
GET<InitChatResponse>(`/chat/init?modelId=${modelId}&chatId=${chatId}`);
export const getInitChatSiteInfo = (data: { appId: string; chatId?: string }) =>
GET<InitChatResponse>(`/chat/init`, data);
/**
* 获取历史记录
*/
export const getChatHistory = (data: RequestPaging) =>
POST<HistoryItemType[]>('/chat/history/getHistory', data);
export const getChatHistory = (data: RequestPaging & { appId?: string }) =>
POST<ChatHistoryItemType[]>('/chat/history/getHistory', data);
/**
* 删除一条历史记录
*/
export const delChatHistoryById = (id: string) => GET(`/chat/removeHistory?id=${id}`);
export const delChatHistoryById = (chatId: string) => DELETE(`/chat/removeHistory`, { chatId });
/**
* get history quotes
* clear all history by appid
*/
export const getHistoryQuote = (params: { chatId: string; historyId: string }) =>
GET<(QuoteItemType & { _id: string })[]>(`/chat/history/getHistoryQuote`, params);
/**
* update history quote status
*/
export const updateHistoryQuote = (params: {
chatId: string;
historyId: string;
quoteId: string;
}) => GET(`/chat/history/updateHistoryQuote`, params);
export const clearChatHistoryByAppId = (appId: string) => DELETE(`/chat/removeHistory`, { appId });
/**
* 删除一句对话
*/
export const delChatRecordByIndex = (chatId: string, contentId: string) =>
DELETE(`/chat/delChatRecordByContentId?chatId=${chatId}&contentId=${contentId}`);
export const delChatRecordById = (data: { chatId: string; contentId: string }) =>
DELETE(`/chat/delChatRecordByContentId`, data);
/**
* 修改历史记录: 标题/置顶
@@ -52,28 +39,28 @@ export const delChatRecordByIndex = (chatId: string, contentId: string) =>
export const putChatHistory = (data: UpdateHistoryProps) =>
PUT('/chat/history/updateChatHistory', data);
/**
* 初始化分享聊天
*/
export const initShareChatInfo = (data: { shareId: string }) =>
GET<InitShareChatResponse>(`/chat/shareChat/init`, data);
/**
* create a shareChat
*/
export const createShareChat = (
data: ShareChatEditType & {
modelId: string;
appId: string;
}
) => POST<string>(`/chat/shareChat/create`, data);
/**
* get shareChat
*/
export const getShareChatList = (modelId: string) =>
GET<ShareChatSchema[]>(`/chat/shareChat/list?modelId=${modelId}`);
export const getShareChatList = (appId: string) =>
GET<OutLinkSchema[]>(`/chat/shareChat/list`, { appId });
/**
* delete a shareChat
*/
export const delShareChatById = (id: string) => DELETE(`/chat/shareChat/delete?id=${id}`);
/**
* 初始化分享聊天
*/
export const initShareChatInfo = (data: { shareId: string; password: string }) =>
GET<InitShareChatResponse>(`/chat/shareChat/init?${Obj2Query(data)}`);

View File

@@ -1 +0,0 @@
import { GET, POST, DELETE } from './request';

View File

@@ -1,67 +1,115 @@
import { GUIDE_PROMPT_HEADER, NEW_CHATID_HEADER, QUOTE_LEN_HEADER } from '@/constants/chat';
import { sseResponseEventEnum, TaskResponseKeyEnum } from '@/constants/chat';
import { getErrText } from '@/utils/tools';
import { parseStreamChunk, SSEParseData } from '@/utils/sse';
import type { ChatHistoryItemResType } from '@/types/chat';
import { StartChatFnProps } from '@/components/ChatBox';
import { getToken } from '@/utils/user';
interface StreamFetchProps {
url: string;
data: any;
onMessage: (text: string) => void;
url?: string;
data: Record<string, any>;
onMessage: StartChatFnProps['generatingMessage'];
abortSignal: AbortController;
}
export const streamFetch = ({ url, data, onMessage, abortSignal }: StreamFetchProps) =>
export const streamFetch = ({
url = '/api/openapi/v1/chat/completions',
data,
onMessage,
abortSignal
}: StreamFetchProps) =>
new Promise<{
responseText: string;
newChatId: string;
systemPrompt: string;
quoteLen: number;
[TaskResponseKeyEnum.responseData]: ChatHistoryItemResType[];
}>(async (resolve, reject) => {
try {
const res = await fetch(url, {
const response = await window.fetch(url, {
method: 'POST',
headers: {
'Content-Type': 'application/json'
'Content-Type': 'application/json',
token: getToken()
},
body: JSON.stringify(data),
signal: abortSignal.signal
signal: abortSignal.signal,
body: JSON.stringify({
...data,
detail: true,
stream: true
})
});
const reader = res.body?.getReader();
if (!reader) return;
const decoder = new TextDecoder();
if (!response?.body) {
throw new Error('Request Error');
}
const newChatId = decodeURIComponent(res.headers.get(NEW_CHATID_HEADER) || '');
const systemPrompt = decodeURIComponent(res.headers.get(GUIDE_PROMPT_HEADER) || '').trim();
const quoteLen = res.headers.get(QUOTE_LEN_HEADER)
? Number(res.headers.get(QUOTE_LEN_HEADER))
: 0;
const reader = response.body?.getReader();
// response data
let responseText = '';
let errMsg = '';
let responseData: ChatHistoryItemResType[] = [];
const parseData = new SSEParseData();
const read = async () => {
try {
const { done, value } = await reader?.read();
const { done, value } = await reader.read();
if (done) {
if (res.status === 200) {
resolve({ responseText, newChatId, quoteLen, systemPrompt });
if (response.status === 200 && !errMsg) {
return resolve({
responseText,
responseData
});
} else {
const parseError = JSON.parse(responseText);
reject(parseError?.message || '请求异常');
return reject({
message: errMsg || '响应过程出现异常~',
responseText
});
}
return;
}
const text = decoder.decode(value);
responseText += text;
onMessage(text);
const chunkResponse = parseStreamChunk(value);
chunkResponse.forEach((item) => {
// parse json data
const { eventName, data } = parseData.parse(item);
if (!eventName || !data) return;
if (eventName === sseResponseEventEnum.answer && data !== '[DONE]') {
const answer: string = data?.choices?.[0]?.delta?.content || '';
onMessage({ text: answer });
responseText += answer;
} else if (
eventName === sseResponseEventEnum.moduleStatus &&
data?.name &&
data?.status
) {
onMessage(data);
} else if (
eventName === sseResponseEventEnum.appStreamResponse &&
Array.isArray(data)
) {
responseData = data;
} else if (eventName === sseResponseEventEnum.error) {
errMsg = getErrText(data, '流响应错误');
}
});
read();
} catch (err: any) {
if (err?.message === 'The user aborted a request.') {
return resolve({ responseText, newChatId, quoteLen, systemPrompt });
return resolve({
responseText,
responseData
});
}
reject(typeof err === 'string' ? err : err?.message || '请求异常');
reject({
responseText,
message: getErrText(err, '请求异常')
});
}
};
read();
} catch (err: any) {
console.log(err, '====');
reject(typeof err === 'string' ? err : err?.message || '请求异常');
console.log(err, 'fetch error');
reject(getErrText(err, '请求异常'));
}
});

View File

@@ -1,44 +0,0 @@
import { GET, POST, DELETE, PUT } from './request';
import type { ModelSchema } from '@/types/mongoSchema';
import type { ModelUpdateParams } from '@/types/model';
import { RequestPaging } from '../types/index';
import type { ModelListResponse } from './response/model';
/**
* 获取模型列表
*/
export const getMyModels = () => GET<ModelListResponse>('/model/list');
/**
* 创建一个模型
*/
export const postCreateModel = (data: { name: string }) => POST<string>('/model/create', data);
/**
* 根据 ID 删除模型
*/
export const delModelById = (id: string) => DELETE(`/model/del?modelId=${id}`);
/**
* 根据 ID 获取模型
*/
export const getModelById = (id: string) => GET<ModelSchema>(`/model/detail?modelId=${id}`);
/**
* 根据 ID 更新模型
*/
export const putModelById = (id: string, data: ModelUpdateParams) =>
PUT(`/model/update?modelId=${id}`, data);
/* 共享市场 */
/**
* 获取共享市场模型
*/
export const getShareModelList = (data: { searchText?: string } & RequestPaging) =>
POST(`/model/share/getModels`, data);
/**
* 收藏/取消收藏模型
*/
export const triggerModelCollection = (modelId: string) =>
POST<number>(`/model/share/collection?modelId=${modelId}`);

View File

@@ -0,0 +1,6 @@
import { GET, POST, PUT, DELETE } from '../request';
import type { FetchResultItem } from '@/types/plugin';
export const fetchUrls = (urlList: string[]) =>
POST<FetchResultItem[]>(`/plugins/urlFetch`, { urlList });

View File

@@ -1,11 +1,17 @@
import { GET, POST, PUT, DELETE } from '../request';
import type { KbItemType } from '@/types/plugin';
import type { KbItemType, KbListItemType } from '@/types/plugin';
import { RequestPaging } from '@/types/index';
import { TrainingModeEnum } from '@/constants/plugin';
import {
Props as PushDataProps,
Response as PushDateResponse
} from '@/pages/api/openapi/kb/pushData';
import {
Props as SearchTestProps,
Response as SearchTestResponse
} from '@/pages/api/openapi/kb/searchTest';
import { Response as KbDataItemType } from '@/pages/api/plugins/kb/data/getDataById';
import { Props as UpdateDataProps } from '@/pages/api/openapi/kb/updateData';
export type KbUpdateParams = {
id: string;
@@ -15,7 +21,7 @@ export type KbUpdateParams = {
};
/* knowledge base */
export const getKbList = () => GET<KbItemType[]>(`/plugins/kb/list`);
export const getKbList = () => GET<KbListItemType[]>(`/plugins/kb/list`);
export const getKbById = (id: string) => GET<KbItemType>(`/plugins/kb/detail?id=${id}`);
@@ -37,7 +43,7 @@ export const getKbDataList = (data: GetKbDataListProps) =>
* 获取导出数据(不分页)
*/
export const getExportDataList = (kbId: string) =>
GET<[string, string][]>(
GET<[string, string, string][]>(
`/plugins/kb/data/exportModelData`,
{ kbId },
{
@@ -54,8 +60,11 @@ export const getTrainingData = (data: { kbId: string; init: boolean }) =>
vectorListLen: number;
}>(`/plugins/kb/data/getTrainingData`, data);
/* get length of system training queue */
export const getTrainingQueueLen = () => GET<number>(`/plugins/kb/data/getQueueLen`);
export const getKbDataItemById = (dataId: string) =>
GET(`/plugins/kb/data/getDataById`, { dataId });
GET<KbDataItemType>(`/plugins/kb/data/getDataById`, { dataId });
/**
* 直接push数据
@@ -66,8 +75,7 @@ export const postKbDataFromList = (data: PushDataProps) =>
/**
* 更新一条数据
*/
export const putKbDataById = (data: { dataId: string; a: string; q?: string }) =>
PUT('/openapi/kb/updateData', data);
export const putKbDataById = (data: UpdateDataProps) => PUT('/openapi/kb/updateData', data);
/**
* 删除一条知识库数据
*/
@@ -83,3 +91,6 @@ export const postSplitData = (data: {
prompt: string;
mode: `${TrainingModeEnum}`;
}) => POST(`/openapi/text/pushData`, data);
export const searchText = (data: SearchTestProps) =>
POST<SearchTestResponse>(`/openapi/kb/searchTest`, data);

View File

@@ -1,5 +1,5 @@
import axios, { Method, InternalAxiosRequestConfig, AxiosResponse } from 'axios';
import { clearCookie } from '@/utils/user';
import { clearToken, getToken } from '@/utils/user';
import { TOKEN_ERROR_CODE } from '@/service/errorCode';
interface ConfigType {
@@ -18,7 +18,7 @@ interface ResponseDataType {
*/
function requestStart(config: InternalAxiosRequestConfig): InternalAxiosRequestConfig {
if (config.headers) {
// config.headers.Authorization = getToken();
config.headers.token = getToken();
}
return config;
@@ -57,12 +57,15 @@ function responseError(err: any) {
}
// 有报错响应
if (err?.code in TOKEN_ERROR_CODE) {
clearCookie();
clearToken();
window.location.replace(
`/login?lastRoute=${encodeURIComponent(location.pathname + location.search)}`
);
return Promise.reject({ message: 'token过期重新登录' });
}
if (err?.response?.data) {
return Promise.reject(err?.response?.data);
}
return Promise.reject(err);
}
@@ -92,8 +95,8 @@ function request(url: string, data: any, config: ConfigType, method: Method): an
baseURL: '/api',
url,
method,
data: method === 'GET' ? null : data,
params: method === 'GET' ? data : null, // get请求不携带dataparams放在url上
data: ['POST', 'PUT'].includes(method) ? data : null,
params: !['POST', 'PUT'].includes(method) ? data : null,
...config // 用户自定义配置,可以覆盖前面的配置
})
.then((res) => checkRes(res.data))
@@ -119,6 +122,6 @@ export function PUT<T>(url: string, data = {}, config: ConfigType = {}): Promise
return request(url, data, config, 'PUT');
}
export function DELETE<T>(url: string, config: ConfigType = {}): Promise<T> {
return request(url, {}, config, 'DELETE');
export function DELETE<T>(url: string, data = {}, config: ConfigType = {}): Promise<T> {
return request(url, data, config, 'DELETE');
}

6
client/src/api/response/app.d.ts vendored Normal file
View File

@@ -0,0 +1,6 @@
import { AppListItemType } from '@/types/app';
export type AppListResponse = {
myApps: AppListItemType[];
myCollectionApps: AppListItemType[];
};

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