balibabu
commited on
Commit
·
452020d
1
Parent(s):
f3d0ebd
feat: add temperature and top-p to ModelSetting and add ChatConfigurationModal and bind backend data to KnowledgeCard (#65)
Browse files* feat: bind backend data to KnowledgeCard
* feat: add ChatConfigurationModal
* feat: add temperature and top-p to ModelSetting
- web/package-lock.json +80 -1
- web/package.json +4 -1
- web/src/assets/svg/chat-configuration-atom.svg +24 -0
- web/src/layouts/components/header/index.less +2 -2
- web/src/pages/add-knowledge/components/knowledge-setting/configuration.tsx +1 -1
- web/src/pages/chat/chat-configuration-modal/assistant-setting.tsx +35 -0
- web/src/pages/chat/chat-configuration-modal/editable-cell.tsx +103 -0
- web/src/pages/chat/chat-configuration-modal/index.less +43 -0
- web/src/pages/chat/chat-configuration-modal/index.tsx +107 -0
- web/src/pages/chat/chat-configuration-modal/interface.ts +3 -0
- web/src/pages/chat/chat-configuration-modal/model-setting.tsx +155 -0
- web/src/pages/chat/chat-configuration-modal/prompt-engine.tsx +163 -0
- web/src/pages/chat/chat-container/index.less +3 -0
- web/src/pages/chat/chat-container/index.tsx +36 -0
- web/src/pages/chat/index.less +25 -0
- web/src/pages/chat/index.tsx +57 -1
- web/src/pages/chat/message-box.tsx +45 -0
- web/src/pages/knowledge/knowledge-card/index.less +1 -1
- web/src/pages/knowledge/knowledge-card/index.tsx +3 -3
web/package-lock.json
CHANGED
@@ -18,16 +18,19 @@
|
|
18 |
"lodash": "^4.17.21",
|
19 |
"moment": "^2.30.1",
|
20 |
"rc-tween-one": "^3.0.6",
|
|
|
21 |
"react-i18next": "^14.0.0",
|
22 |
"react-infinite-scroll-component": "^6.1.0",
|
23 |
"umi": "^4.0.90",
|
24 |
-
"umi-request": "^1.4.0"
|
|
|
25 |
},
|
26 |
"devDependencies": {
|
27 |
"@react-dev-inspector/umi4-plugin": "^2.0.1",
|
28 |
"@types/lodash": "^4.14.202",
|
29 |
"@types/react": "^18.0.33",
|
30 |
"@types/react-dom": "^18.0.11",
|
|
|
31 |
"@umijs/lint": "^4.1.1",
|
32 |
"@umijs/plugins": "^4.1.0",
|
33 |
"cross-env": "^7.0.3",
|
@@ -2929,6 +2932,12 @@
|
|
2929 |
"integrity": "sha512-EwmlvuaxPNej9+T4v5AuBPJa2x2UOJVdjCtDHgcDqitUeOtjnJKJ+apYjVcAoBEMjKW1VVFGZLUb5+qqa09XFA==",
|
2930 |
"dev": true
|
2931 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
2932 |
"node_modules/@types/yargs": {
|
2933 |
"version": "16.0.9",
|
2934 |
"resolved": "https://registry.npmmirror.com/@types/yargs/-/yargs-16.0.9.tgz",
|
@@ -10669,6 +10678,11 @@
|
|
10669 |
"node": ">=8.9.0"
|
10670 |
}
|
10671 |
},
|
|
|
|
|
|
|
|
|
|
|
10672 |
"node_modules/local-pkg": {
|
10673 |
"version": "0.4.3",
|
10674 |
"resolved": "https://registry.npmmirror.com/local-pkg/-/local-pkg-0.4.3.tgz",
|
@@ -12666,6 +12680,15 @@
|
|
12666 |
"resolved": "https://registry.npmmirror.com/process-warning/-/process-warning-1.0.0.tgz",
|
12667 |
"integrity": "sha512-du4wfLyj4yCZq1VupnVSZmRsPJsNuxoDQFdCFHLaYiEbFBD7QE0a+I4D7hOxrVnh78QE/YipFAj9lXHiXocV+Q=="
|
12668 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
12669 |
"node_modules/prompts": {
|
12670 |
"version": "2.4.2",
|
12671 |
"resolved": "https://registry.npmmirror.com/prompts/-/prompts-2.4.2.tgz",
|
@@ -13446,6 +13469,22 @@
|
|
13446 |
"node": ">=0.10.0"
|
13447 |
}
|
13448 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
13449 |
"node_modules/react-dev-inspector": {
|
13450 |
"version": "2.0.1",
|
13451 |
"resolved": "https://registry.npmmirror.com/react-dev-inspector/-/react-dev-inspector-2.0.1.tgz",
|
@@ -13784,6 +13823,14 @@
|
|
13784 |
}
|
13785 |
}
|
13786 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
13787 |
"node_modules/react-infinite-scroll-component": {
|
13788 |
"version": "6.1.0",
|
13789 |
"resolved": "https://registry.npmmirror.com/react-infinite-scroll-component/-/react-infinite-scroll-component-6.1.0.tgz",
|
@@ -13924,6 +13971,17 @@
|
|
13924 |
"react": ">=15"
|
13925 |
}
|
13926 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
13927 |
"node_modules/reactcss": {
|
13928 |
"version": "1.2.3",
|
13929 |
"resolved": "https://registry.npmmirror.com/reactcss/-/reactcss-1.2.3.tgz",
|
@@ -14633,6 +14691,14 @@
|
|
14633 |
"integrity": "sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==",
|
14634 |
"dev": true
|
14635 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
14636 |
"node_modules/side-channel": {
|
14637 |
"version": "1.0.4",
|
14638 |
"resolved": "https://registry.npmmirror.com/side-channel/-/side-channel-1.0.4.tgz",
|
@@ -15783,6 +15849,11 @@
|
|
15783 |
"node": ">=12.22"
|
15784 |
}
|
15785 |
},
|
|
|
|
|
|
|
|
|
|
|
15786 |
"node_modules/timers-browserify": {
|
15787 |
"version": "2.0.12",
|
15788 |
"resolved": "https://registry.npmmirror.com/timers-browserify/-/timers-browserify-2.0.12.tgz",
|
@@ -16859,6 +16930,14 @@
|
|
16859 |
"resolved": "https://registry.npmmirror.com/utila/-/utila-0.4.0.tgz",
|
16860 |
"integrity": "sha512-Z0DbgELS9/L/75wZbro8xAnT50pBVFQZ+hUEueGDU5FN51YSCYM+jdxsfCiHjwNP/4LCDD0i/graKpeBnOXKRA=="
|
16861 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
16862 |
"node_modules/v8-compile-cache": {
|
16863 |
"version": "2.4.0",
|
16864 |
"resolved": "https://registry.npmmirror.com/v8-compile-cache/-/v8-compile-cache-2.4.0.tgz",
|
|
|
18 |
"lodash": "^4.17.21",
|
19 |
"moment": "^2.30.1",
|
20 |
"rc-tween-one": "^3.0.6",
|
21 |
+
"react-chat-elements": "^12.0.13",
|
22 |
"react-i18next": "^14.0.0",
|
23 |
"react-infinite-scroll-component": "^6.1.0",
|
24 |
"umi": "^4.0.90",
|
25 |
+
"umi-request": "^1.4.0",
|
26 |
+
"uuid": "^9.0.1"
|
27 |
},
|
28 |
"devDependencies": {
|
29 |
"@react-dev-inspector/umi4-plugin": "^2.0.1",
|
30 |
"@types/lodash": "^4.14.202",
|
31 |
"@types/react": "^18.0.33",
|
32 |
"@types/react-dom": "^18.0.11",
|
33 |
+
"@types/uuid": "^9.0.8",
|
34 |
"@umijs/lint": "^4.1.1",
|
35 |
"@umijs/plugins": "^4.1.0",
|
36 |
"cross-env": "^7.0.3",
|
|
|
2932 |
"integrity": "sha512-EwmlvuaxPNej9+T4v5AuBPJa2x2UOJVdjCtDHgcDqitUeOtjnJKJ+apYjVcAoBEMjKW1VVFGZLUb5+qqa09XFA==",
|
2933 |
"dev": true
|
2934 |
},
|
2935 |
+
"node_modules/@types/uuid": {
|
2936 |
+
"version": "9.0.8",
|
2937 |
+
"resolved": "https://registry.npmmirror.com/@types/uuid/-/uuid-9.0.8.tgz",
|
2938 |
+
"integrity": "sha512-jg+97EGIcY9AGHJJRaaPVgetKDsrTgbRjQ5Msgjh/DQKEFl0DtyRr/VCOyD1T2R1MNeWPK/u7JoGhlDZnKBAfA==",
|
2939 |
+
"dev": true
|
2940 |
+
},
|
2941 |
"node_modules/@types/yargs": {
|
2942 |
"version": "16.0.9",
|
2943 |
"resolved": "https://registry.npmmirror.com/@types/yargs/-/yargs-16.0.9.tgz",
|
|
|
10678 |
"node": ">=8.9.0"
|
10679 |
}
|
10680 |
},
|
10681 |
+
"node_modules/loaders.css": {
|
10682 |
+
"version": "0.1.2",
|
10683 |
+
"resolved": "https://registry.npmmirror.com/loaders.css/-/loaders.css-0.1.2.tgz",
|
10684 |
+
"integrity": "sha512-Rhowlq24ey1VOeor+3wYOt9+MjaxBOJm1u4KlQgNC3+0xJ0LS4wq4iG57D/BPzvuD/7HHDGQOWJ+81oR2EI9bQ=="
|
10685 |
+
},
|
10686 |
"node_modules/local-pkg": {
|
10687 |
"version": "0.4.3",
|
10688 |
"resolved": "https://registry.npmmirror.com/local-pkg/-/local-pkg-0.4.3.tgz",
|
|
|
12680 |
"resolved": "https://registry.npmmirror.com/process-warning/-/process-warning-1.0.0.tgz",
|
12681 |
"integrity": "sha512-du4wfLyj4yCZq1VupnVSZmRsPJsNuxoDQFdCFHLaYiEbFBD7QE0a+I4D7hOxrVnh78QE/YipFAj9lXHiXocV+Q=="
|
12682 |
},
|
12683 |
+
"node_modules/progressbar.js": {
|
12684 |
+
"version": "1.1.1",
|
12685 |
+
"resolved": "https://registry.npmmirror.com/progressbar.js/-/progressbar.js-1.1.1.tgz",
|
12686 |
+
"integrity": "sha512-FBsw3BKsUbb+hNeYfiP3xzvAAQrPi4DnGDw66bCmfuRCDLcslxyxv2GyYUdBSKFGSIBa73CUP5WMcl6F8AAXlw==",
|
12687 |
+
"dependencies": {
|
12688 |
+
"lodash.merge": "^4.6.2",
|
12689 |
+
"shifty": "^2.8.3"
|
12690 |
+
}
|
12691 |
+
},
|
12692 |
"node_modules/prompts": {
|
12693 |
"version": "2.4.2",
|
12694 |
"resolved": "https://registry.npmmirror.com/prompts/-/prompts-2.4.2.tgz",
|
|
|
13469 |
"node": ">=0.10.0"
|
13470 |
}
|
13471 |
},
|
13472 |
+
"node_modules/react-chat-elements": {
|
13473 |
+
"version": "12.0.13",
|
13474 |
+
"resolved": "https://registry.npmmirror.com/react-chat-elements/-/react-chat-elements-12.0.13.tgz",
|
13475 |
+
"integrity": "sha512-Vu5x8kW4LPu8onKfz5vsuDwZsDhoQmTBHJdqKAhVsi42PCQ8KOfzHiDp0fPUJlinJZ/MTJTm69UAchpys4iSTQ==",
|
13476 |
+
"dependencies": {
|
13477 |
+
"classnames": "^2.2.5",
|
13478 |
+
"progressbar.js": "^1.1.0",
|
13479 |
+
"react-icons": "^4.3.1",
|
13480 |
+
"react-spinkit": "^3.0.0",
|
13481 |
+
"timeago.js": "^4.0.2"
|
13482 |
+
},
|
13483 |
+
"peerDependencies": {
|
13484 |
+
"react": "^18.2.0",
|
13485 |
+
"react-dom": "18.2.0"
|
13486 |
+
}
|
13487 |
+
},
|
13488 |
"node_modules/react-dev-inspector": {
|
13489 |
"version": "2.0.1",
|
13490 |
"resolved": "https://registry.npmmirror.com/react-dev-inspector/-/react-dev-inspector-2.0.1.tgz",
|
|
|
13823 |
}
|
13824 |
}
|
13825 |
},
|
13826 |
+
"node_modules/react-icons": {
|
13827 |
+
"version": "4.12.0",
|
13828 |
+
"resolved": "https://registry.npmmirror.com/react-icons/-/react-icons-4.12.0.tgz",
|
13829 |
+
"integrity": "sha512-IBaDuHiShdZqmfc/TwHu6+d6k2ltNCf3AszxNmjJc1KUfXdEeRJOKyNvLmAHaarhzGmTSVygNdyu8/opXv2gaw==",
|
13830 |
+
"peerDependencies": {
|
13831 |
+
"react": "*"
|
13832 |
+
}
|
13833 |
+
},
|
13834 |
"node_modules/react-infinite-scroll-component": {
|
13835 |
"version": "6.1.0",
|
13836 |
"resolved": "https://registry.npmmirror.com/react-infinite-scroll-component/-/react-infinite-scroll-component-6.1.0.tgz",
|
|
|
13971 |
"react": ">=15"
|
13972 |
}
|
13973 |
},
|
13974 |
+
"node_modules/react-spinkit": {
|
13975 |
+
"version": "3.0.0",
|
13976 |
+
"resolved": "https://registry.npmmirror.com/react-spinkit/-/react-spinkit-3.0.0.tgz",
|
13977 |
+
"integrity": "sha512-RrfGRPjqxHQiy7quPqhjPynTu0zobgQaZu1QYBMpJJ6pCSRRRK16EZMaxdE6fLVYFRJWpX/eGATWLMoVFFT5uQ==",
|
13978 |
+
"dependencies": {
|
13979 |
+
"classnames": "^2.2.3",
|
13980 |
+
"loaders.css": "^0.1.2",
|
13981 |
+
"object-assign": "^4.1.0",
|
13982 |
+
"prop-types": "^15.5.8"
|
13983 |
+
}
|
13984 |
+
},
|
13985 |
"node_modules/reactcss": {
|
13986 |
"version": "1.2.3",
|
13987 |
"resolved": "https://registry.npmmirror.com/reactcss/-/reactcss-1.2.3.tgz",
|
|
|
14691 |
"integrity": "sha512-6j1W9l1iAs/4xYBI1SYOVZyFcCis9b4KCLQ8fgAGG07QvzaRLVVRQvAy85yNmmZSjYjg4MWh4gNvlPujU/5LpA==",
|
14692 |
"dev": true
|
14693 |
},
|
14694 |
+
"node_modules/shifty": {
|
14695 |
+
"version": "2.20.4",
|
14696 |
+
"resolved": "https://registry.npmmirror.com/shifty/-/shifty-2.20.4.tgz",
|
14697 |
+
"integrity": "sha512-4Y0qRkg8ME5XN8yGNAwmFOmsIURGFKT9UQfNL6DDJQErYtN5HsjyoBuJn41ZQfTkuu2rIbRMn9qazjKsDpO2TA==",
|
14698 |
+
"optionalDependencies": {
|
14699 |
+
"fsevents": "^2.3.2"
|
14700 |
+
}
|
14701 |
+
},
|
14702 |
"node_modules/side-channel": {
|
14703 |
"version": "1.0.4",
|
14704 |
"resolved": "https://registry.npmmirror.com/side-channel/-/side-channel-1.0.4.tgz",
|
|
|
15849 |
"node": ">=12.22"
|
15850 |
}
|
15851 |
},
|
15852 |
+
"node_modules/timeago.js": {
|
15853 |
+
"version": "4.0.2",
|
15854 |
+
"resolved": "https://registry.npmmirror.com/timeago.js/-/timeago.js-4.0.2.tgz",
|
15855 |
+
"integrity": "sha512-a7wPxPdVlQL7lqvitHGGRsofhdwtkoSXPGATFuSOA2i1ZNQEPLrGnj68vOp2sOJTCFAQVXPeNMX/GctBaO9L2w=="
|
15856 |
+
},
|
15857 |
"node_modules/timers-browserify": {
|
15858 |
"version": "2.0.12",
|
15859 |
"resolved": "https://registry.npmmirror.com/timers-browserify/-/timers-browserify-2.0.12.tgz",
|
|
|
16930 |
"resolved": "https://registry.npmmirror.com/utila/-/utila-0.4.0.tgz",
|
16931 |
"integrity": "sha512-Z0DbgELS9/L/75wZbro8xAnT50pBVFQZ+hUEueGDU5FN51YSCYM+jdxsfCiHjwNP/4LCDD0i/graKpeBnOXKRA=="
|
16932 |
},
|
16933 |
+
"node_modules/uuid": {
|
16934 |
+
"version": "9.0.1",
|
16935 |
+
"resolved": "https://registry.npmmirror.com/uuid/-/uuid-9.0.1.tgz",
|
16936 |
+
"integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==",
|
16937 |
+
"bin": {
|
16938 |
+
"uuid": "dist/bin/uuid"
|
16939 |
+
}
|
16940 |
+
},
|
16941 |
"node_modules/v8-compile-cache": {
|
16942 |
"version": "2.4.0",
|
16943 |
"resolved": "https://registry.npmmirror.com/v8-compile-cache/-/v8-compile-cache-2.4.0.tgz",
|
web/package.json
CHANGED
@@ -22,16 +22,19 @@
|
|
22 |
"lodash": "^4.17.21",
|
23 |
"moment": "^2.30.1",
|
24 |
"rc-tween-one": "^3.0.6",
|
|
|
25 |
"react-i18next": "^14.0.0",
|
26 |
"react-infinite-scroll-component": "^6.1.0",
|
27 |
"umi": "^4.0.90",
|
28 |
-
"umi-request": "^1.4.0"
|
|
|
29 |
},
|
30 |
"devDependencies": {
|
31 |
"@react-dev-inspector/umi4-plugin": "^2.0.1",
|
32 |
"@types/lodash": "^4.14.202",
|
33 |
"@types/react": "^18.0.33",
|
34 |
"@types/react-dom": "^18.0.11",
|
|
|
35 |
"@umijs/lint": "^4.1.1",
|
36 |
"@umijs/plugins": "^4.1.0",
|
37 |
"cross-env": "^7.0.3",
|
|
|
22 |
"lodash": "^4.17.21",
|
23 |
"moment": "^2.30.1",
|
24 |
"rc-tween-one": "^3.0.6",
|
25 |
+
"react-chat-elements": "^12.0.13",
|
26 |
"react-i18next": "^14.0.0",
|
27 |
"react-infinite-scroll-component": "^6.1.0",
|
28 |
"umi": "^4.0.90",
|
29 |
+
"umi-request": "^1.4.0",
|
30 |
+
"uuid": "^9.0.1"
|
31 |
},
|
32 |
"devDependencies": {
|
33 |
"@react-dev-inspector/umi4-plugin": "^2.0.1",
|
34 |
"@types/lodash": "^4.14.202",
|
35 |
"@types/react": "^18.0.33",
|
36 |
"@types/react-dom": "^18.0.11",
|
37 |
+
"@types/uuid": "^9.0.8",
|
38 |
"@umijs/lint": "^4.1.1",
|
39 |
"@umijs/plugins": "^4.1.0",
|
40 |
"cross-env": "^7.0.3",
|
web/src/assets/svg/chat-configuration-atom.svg
ADDED
|
web/src/layouts/components/header/index.less
CHANGED
@@ -19,9 +19,9 @@
|
|
19 |
.appName {
|
20 |
vertical-align: middle;
|
21 |
font-family: Inter;
|
22 |
-
font-size:
|
23 |
font-style: normal;
|
24 |
-
font-weight:
|
25 |
line-height: 20px;
|
26 |
}
|
27 |
|
|
|
19 |
.appName {
|
20 |
vertical-align: middle;
|
21 |
font-family: Inter;
|
22 |
+
font-size: 16px;
|
23 |
font-style: normal;
|
24 |
+
font-weight: 600;
|
25 |
line-height: 20px;
|
26 |
}
|
27 |
|
web/src/pages/add-knowledge/components/knowledge-setting/configuration.tsx
CHANGED
@@ -68,7 +68,7 @@ const Configuration = () => {
|
|
68 |
const fileList = values.avatar;
|
69 |
let avatar;
|
70 |
|
71 |
-
if (Array.isArray(fileList)) {
|
72 |
avatar = fileList[0].thumbUrl;
|
73 |
}
|
74 |
|
|
|
68 |
const fileList = values.avatar;
|
69 |
let avatar;
|
70 |
|
71 |
+
if (Array.isArray(fileList) && fileList.length > 0) {
|
72 |
avatar = fileList[0].thumbUrl;
|
73 |
}
|
74 |
|
web/src/pages/chat/chat-configuration-modal/assistant-setting.tsx
ADDED
@@ -0,0 +1,35 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import { Form, Input } from 'antd';
|
2 |
+
|
3 |
+
import classNames from 'classnames';
|
4 |
+
import { ISegmentedContentProps } from './interface';
|
5 |
+
|
6 |
+
import styles from './index.less';
|
7 |
+
|
8 |
+
const AssistantSetting = ({ show }: ISegmentedContentProps) => {
|
9 |
+
return (
|
10 |
+
<section
|
11 |
+
className={classNames({
|
12 |
+
[styles.segmentedHidden]: !show,
|
13 |
+
})}
|
14 |
+
>
|
15 |
+
<Form.Item
|
16 |
+
name={'name'}
|
17 |
+
label="Assistant name"
|
18 |
+
rules={[{ required: true }]}
|
19 |
+
>
|
20 |
+
<Input placeholder="e.g. Resume Jarvis" />
|
21 |
+
</Form.Item>
|
22 |
+
<Form.Item name={'avatar'} label="Assistant avatar">
|
23 |
+
<Input />
|
24 |
+
</Form.Item>
|
25 |
+
<Form.Item name={'keywords'} label="Keywords">
|
26 |
+
<Input.TextArea autoSize={{ minRows: 3 }} />
|
27 |
+
</Form.Item>
|
28 |
+
<Form.Item name={'opener'} label="Set an opener">
|
29 |
+
<Input.TextArea autoSize={{ minRows: 5 }} />
|
30 |
+
</Form.Item>
|
31 |
+
</section>
|
32 |
+
);
|
33 |
+
};
|
34 |
+
|
35 |
+
export default AssistantSetting;
|
web/src/pages/chat/chat-configuration-modal/editable-cell.tsx
ADDED
@@ -0,0 +1,103 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import { Form, FormInstance, Input, InputRef } from 'antd';
|
2 |
+
import React, { useContext, useEffect, useRef, useState } from 'react';
|
3 |
+
|
4 |
+
const EditableContext = React.createContext<FormInstance<any> | null>(null);
|
5 |
+
|
6 |
+
interface EditableRowProps {
|
7 |
+
index: number;
|
8 |
+
}
|
9 |
+
|
10 |
+
interface Item {
|
11 |
+
key: string;
|
12 |
+
name: string;
|
13 |
+
age: string;
|
14 |
+
address: string;
|
15 |
+
}
|
16 |
+
|
17 |
+
export const EditableRow: React.FC<EditableRowProps> = ({
|
18 |
+
index,
|
19 |
+
...props
|
20 |
+
}) => {
|
21 |
+
const [form] = Form.useForm();
|
22 |
+
return (
|
23 |
+
<Form form={form} component={false}>
|
24 |
+
<EditableContext.Provider value={form}>
|
25 |
+
<tr {...props} />
|
26 |
+
</EditableContext.Provider>
|
27 |
+
</Form>
|
28 |
+
);
|
29 |
+
};
|
30 |
+
|
31 |
+
interface EditableCellProps {
|
32 |
+
title: React.ReactNode;
|
33 |
+
editable: boolean;
|
34 |
+
children: React.ReactNode;
|
35 |
+
dataIndex: keyof Item;
|
36 |
+
record: Item;
|
37 |
+
handleSave: (record: Item) => void;
|
38 |
+
}
|
39 |
+
|
40 |
+
export const EditableCell: React.FC<EditableCellProps> = ({
|
41 |
+
title,
|
42 |
+
editable,
|
43 |
+
children,
|
44 |
+
dataIndex,
|
45 |
+
record,
|
46 |
+
handleSave,
|
47 |
+
...restProps
|
48 |
+
}) => {
|
49 |
+
const [editing, setEditing] = useState(false);
|
50 |
+
const inputRef = useRef<InputRef>(null);
|
51 |
+
const form = useContext(EditableContext)!;
|
52 |
+
|
53 |
+
useEffect(() => {
|
54 |
+
if (editing) {
|
55 |
+
inputRef.current!.focus();
|
56 |
+
}
|
57 |
+
}, [editing]);
|
58 |
+
|
59 |
+
const toggleEdit = () => {
|
60 |
+
setEditing(!editing);
|
61 |
+
form.setFieldsValue({ [dataIndex]: record[dataIndex] });
|
62 |
+
};
|
63 |
+
|
64 |
+
const save = async () => {
|
65 |
+
try {
|
66 |
+
const values = await form.validateFields();
|
67 |
+
|
68 |
+
toggleEdit();
|
69 |
+
handleSave({ ...record, ...values });
|
70 |
+
} catch (errInfo) {
|
71 |
+
console.log('Save failed:', errInfo);
|
72 |
+
}
|
73 |
+
};
|
74 |
+
|
75 |
+
let childNode = children;
|
76 |
+
|
77 |
+
if (editable) {
|
78 |
+
childNode = editing ? (
|
79 |
+
<Form.Item
|
80 |
+
style={{ margin: 0 }}
|
81 |
+
name={dataIndex}
|
82 |
+
rules={[
|
83 |
+
{
|
84 |
+
required: true,
|
85 |
+
message: `${title} is required.`,
|
86 |
+
},
|
87 |
+
]}
|
88 |
+
>
|
89 |
+
<Input ref={inputRef} onPressEnter={save} onBlur={save} />
|
90 |
+
</Form.Item>
|
91 |
+
) : (
|
92 |
+
<div
|
93 |
+
className="editable-cell-value-wrap"
|
94 |
+
style={{ paddingRight: 24 }}
|
95 |
+
onClick={toggleEdit}
|
96 |
+
>
|
97 |
+
{children}
|
98 |
+
</div>
|
99 |
+
);
|
100 |
+
}
|
101 |
+
|
102 |
+
return <td {...restProps}>{childNode}</td>;
|
103 |
+
};
|
web/src/pages/chat/chat-configuration-modal/index.less
ADDED
@@ -0,0 +1,43 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
.chatConfigurationDescription {
|
2 |
+
font-size: 14px;
|
3 |
+
}
|
4 |
+
|
5 |
+
.variableContainer {
|
6 |
+
padding-bottom: 20px;
|
7 |
+
.variableAlign {
|
8 |
+
text-align: right;
|
9 |
+
}
|
10 |
+
|
11 |
+
.variableLabel {
|
12 |
+
margin-right: 16px;
|
13 |
+
}
|
14 |
+
|
15 |
+
.variableTable {
|
16 |
+
margin-top: 14px;
|
17 |
+
}
|
18 |
+
.editableRow {
|
19 |
+
:global(.editable-cell) {
|
20 |
+
position: relative;
|
21 |
+
}
|
22 |
+
|
23 |
+
:global(.editable-cell-value-wrap) {
|
24 |
+
padding: 5px 12px;
|
25 |
+
cursor: pointer;
|
26 |
+
height: 22px !important;
|
27 |
+
}
|
28 |
+
&:hover {
|
29 |
+
:global(.editable-cell-value-wrap) {
|
30 |
+
padding: 4px 11px;
|
31 |
+
border: 1px solid #d9d9d9;
|
32 |
+
border-radius: 2px;
|
33 |
+
}
|
34 |
+
}
|
35 |
+
}
|
36 |
+
}
|
37 |
+
|
38 |
+
.segmentedHidden {
|
39 |
+
opacity: 0;
|
40 |
+
height: 0;
|
41 |
+
width: 0;
|
42 |
+
margin: 0;
|
43 |
+
}
|
web/src/pages/chat/chat-configuration-modal/index.tsx
ADDED
@@ -0,0 +1,107 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import { ReactComponent as ChatConfigurationAtom } from '@/assets/svg/chat-configuration-atom.svg';
|
2 |
+
import { IModalManagerChildrenProps } from '@/components/modal-manager';
|
3 |
+
import { Divider, Flex, Form, Modal, Segmented } from 'antd';
|
4 |
+
import { SegmentedValue } from 'antd/es/segmented';
|
5 |
+
import { useState } from 'react';
|
6 |
+
import AssistantSetting from './assistant-setting';
|
7 |
+
import ModelSetting from './model-setting';
|
8 |
+
import PromptEngine from './prompt-engine';
|
9 |
+
|
10 |
+
import styles from './index.less';
|
11 |
+
|
12 |
+
enum ConfigurationSegmented {
|
13 |
+
AssistantSetting = 'Assistant Setting',
|
14 |
+
ModelSetting = 'Model Setting',
|
15 |
+
PromptEngine = 'Prompt Engine',
|
16 |
+
}
|
17 |
+
|
18 |
+
const segmentedMap = {
|
19 |
+
[ConfigurationSegmented.AssistantSetting]: AssistantSetting,
|
20 |
+
[ConfigurationSegmented.ModelSetting]: ModelSetting,
|
21 |
+
[ConfigurationSegmented.PromptEngine]: PromptEngine,
|
22 |
+
};
|
23 |
+
|
24 |
+
const layout = {
|
25 |
+
labelCol: { span: 6 },
|
26 |
+
wrapperCol: { span: 18 },
|
27 |
+
};
|
28 |
+
|
29 |
+
const validateMessages = {
|
30 |
+
required: '${label} is required!',
|
31 |
+
types: {
|
32 |
+
email: '${label} is not a valid email!',
|
33 |
+
number: '${label} is not a valid number!',
|
34 |
+
},
|
35 |
+
number: {
|
36 |
+
range: '${label} must be between ${min} and ${max}',
|
37 |
+
},
|
38 |
+
};
|
39 |
+
|
40 |
+
const ChatConfigurationModal = ({
|
41 |
+
visible,
|
42 |
+
hideModal,
|
43 |
+
}: IModalManagerChildrenProps) => {
|
44 |
+
const [form] = Form.useForm();
|
45 |
+
const [value, setValue] = useState<ConfigurationSegmented>(
|
46 |
+
ConfigurationSegmented.AssistantSetting,
|
47 |
+
);
|
48 |
+
|
49 |
+
const handleOk = async () => {
|
50 |
+
const x = await form.validateFields();
|
51 |
+
console.info(x);
|
52 |
+
};
|
53 |
+
|
54 |
+
const handleCancel = () => {
|
55 |
+
hideModal();
|
56 |
+
};
|
57 |
+
|
58 |
+
const handleSegmentedChange = (val: SegmentedValue) => {
|
59 |
+
setValue(val as ConfigurationSegmented);
|
60 |
+
};
|
61 |
+
|
62 |
+
const title = (
|
63 |
+
<Flex gap={16}>
|
64 |
+
<ChatConfigurationAtom></ChatConfigurationAtom>
|
65 |
+
<div>
|
66 |
+
<b>Chat Configuration</b>
|
67 |
+
<div className={styles.chatConfigurationDescription}>
|
68 |
+
Here, dress up a dedicated assistant for your special knowledge bases!
|
69 |
+
💕
|
70 |
+
</div>
|
71 |
+
</div>
|
72 |
+
</Flex>
|
73 |
+
);
|
74 |
+
|
75 |
+
return (
|
76 |
+
<Modal
|
77 |
+
title={title}
|
78 |
+
width={688}
|
79 |
+
open={visible}
|
80 |
+
onOk={handleOk}
|
81 |
+
onCancel={handleCancel}
|
82 |
+
>
|
83 |
+
<Segmented
|
84 |
+
size={'large'}
|
85 |
+
value={value}
|
86 |
+
onChange={handleSegmentedChange}
|
87 |
+
options={Object.values(ConfigurationSegmented)}
|
88 |
+
block
|
89 |
+
/>
|
90 |
+
<Divider></Divider>
|
91 |
+
<Form
|
92 |
+
{...layout}
|
93 |
+
name="nest-messages"
|
94 |
+
form={form}
|
95 |
+
style={{ maxWidth: 600 }}
|
96 |
+
validateMessages={validateMessages}
|
97 |
+
colon={false}
|
98 |
+
>
|
99 |
+
{Object.entries(segmentedMap).map(([key, Element]) => (
|
100 |
+
<Element key={key} show={key === value}></Element>
|
101 |
+
))}
|
102 |
+
</Form>
|
103 |
+
</Modal>
|
104 |
+
);
|
105 |
+
};
|
106 |
+
|
107 |
+
export default ChatConfigurationModal;
|
web/src/pages/chat/chat-configuration-modal/interface.ts
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
export interface ISegmentedContentProps {
|
2 |
+
show: boolean;
|
3 |
+
}
|
web/src/pages/chat/chat-configuration-modal/model-setting.tsx
ADDED
@@ -0,0 +1,155 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import { Divider, Flex, Form, InputNumber, Select, Slider } from 'antd';
|
2 |
+
import classNames from 'classnames';
|
3 |
+
import { ISegmentedContentProps } from './interface';
|
4 |
+
|
5 |
+
import styles from './index.less';
|
6 |
+
|
7 |
+
const { Option } = Select;
|
8 |
+
|
9 |
+
const ModelSetting = ({ show }: ISegmentedContentProps) => {
|
10 |
+
return (
|
11 |
+
<section
|
12 |
+
className={classNames({
|
13 |
+
[styles.segmentedHidden]: !show,
|
14 |
+
})}
|
15 |
+
>
|
16 |
+
<Form.Item
|
17 |
+
label="Model"
|
18 |
+
name="model"
|
19 |
+
// rules={[{ required: true, message: 'Please input!' }]}
|
20 |
+
>
|
21 |
+
<Select />
|
22 |
+
</Form.Item>
|
23 |
+
<Divider></Divider>
|
24 |
+
<Form.Item
|
25 |
+
label="Parameters"
|
26 |
+
name="parameters"
|
27 |
+
// rules={[{ required: true, message: 'Please input!' }]}
|
28 |
+
>
|
29 |
+
<Select />
|
30 |
+
</Form.Item>
|
31 |
+
<Form.Item label="Temperature">
|
32 |
+
<Flex gap={20}>
|
33 |
+
<Flex flex={1}>
|
34 |
+
<Form.Item
|
35 |
+
name={['address', 'province']}
|
36 |
+
noStyle
|
37 |
+
rules={[{ required: true, message: 'Province is required' }]}
|
38 |
+
>
|
39 |
+
<Slider style={{ display: 'inline-block', width: '100%' }} />
|
40 |
+
</Form.Item>
|
41 |
+
</Flex>
|
42 |
+
<Form.Item
|
43 |
+
name={['address', 'street']}
|
44 |
+
noStyle
|
45 |
+
rules={[{ required: true, message: 'Street is required' }]}
|
46 |
+
>
|
47 |
+
<InputNumber
|
48 |
+
style={{
|
49 |
+
width: 50,
|
50 |
+
}}
|
51 |
+
/>
|
52 |
+
</Form.Item>
|
53 |
+
</Flex>
|
54 |
+
</Form.Item>
|
55 |
+
<Form.Item label="Top P">
|
56 |
+
<Flex gap={20}>
|
57 |
+
<Flex flex={1}>
|
58 |
+
<Form.Item
|
59 |
+
name={['address', 'province']}
|
60 |
+
noStyle
|
61 |
+
rules={[{ required: true, message: 'Province is required' }]}
|
62 |
+
>
|
63 |
+
<Slider style={{ display: 'inline-block', width: '100%' }} />
|
64 |
+
</Form.Item>
|
65 |
+
</Flex>
|
66 |
+
<Form.Item
|
67 |
+
name={['address', 'street']}
|
68 |
+
noStyle
|
69 |
+
rules={[{ required: true, message: 'Street is required' }]}
|
70 |
+
>
|
71 |
+
<InputNumber
|
72 |
+
style={{
|
73 |
+
width: 50,
|
74 |
+
}}
|
75 |
+
/>
|
76 |
+
</Form.Item>
|
77 |
+
</Flex>
|
78 |
+
</Form.Item>
|
79 |
+
<Form.Item label="Presence Penalty">
|
80 |
+
<Flex gap={20}>
|
81 |
+
<Flex flex={1}>
|
82 |
+
<Form.Item
|
83 |
+
name={['address', 'province']}
|
84 |
+
noStyle
|
85 |
+
rules={[{ required: true, message: 'Province is required' }]}
|
86 |
+
>
|
87 |
+
<Slider style={{ display: 'inline-block', width: '100%' }} />
|
88 |
+
</Form.Item>
|
89 |
+
</Flex>
|
90 |
+
<Form.Item
|
91 |
+
name={['address', 'street']}
|
92 |
+
noStyle
|
93 |
+
rules={[{ required: true, message: 'Street is required' }]}
|
94 |
+
>
|
95 |
+
<InputNumber
|
96 |
+
style={{
|
97 |
+
width: 50,
|
98 |
+
}}
|
99 |
+
/>
|
100 |
+
</Form.Item>
|
101 |
+
</Flex>
|
102 |
+
</Form.Item>
|
103 |
+
<Form.Item label="Frequency Penalty">
|
104 |
+
<Flex gap={20}>
|
105 |
+
<Flex flex={1}>
|
106 |
+
<Form.Item
|
107 |
+
name={['address', 'province']}
|
108 |
+
noStyle
|
109 |
+
rules={[{ required: true, message: 'Province is required' }]}
|
110 |
+
>
|
111 |
+
<Slider style={{ display: 'inline-block', width: '100%' }} />
|
112 |
+
</Form.Item>
|
113 |
+
</Flex>
|
114 |
+
<Form.Item
|
115 |
+
name={['address', 'street']}
|
116 |
+
noStyle
|
117 |
+
rules={[{ required: true, message: 'Street is required' }]}
|
118 |
+
>
|
119 |
+
<InputNumber
|
120 |
+
style={{
|
121 |
+
width: 50,
|
122 |
+
}}
|
123 |
+
/>
|
124 |
+
</Form.Item>
|
125 |
+
</Flex>
|
126 |
+
</Form.Item>
|
127 |
+
<Form.Item label="Max Tokens">
|
128 |
+
<Flex gap={20}>
|
129 |
+
<Flex flex={1}>
|
130 |
+
<Form.Item
|
131 |
+
name={['address', 'province']}
|
132 |
+
noStyle
|
133 |
+
rules={[{ required: true, message: 'Province is required' }]}
|
134 |
+
>
|
135 |
+
<Slider style={{ display: 'inline-block', width: '100%' }} />
|
136 |
+
</Form.Item>
|
137 |
+
</Flex>
|
138 |
+
<Form.Item
|
139 |
+
name={['address', 'street']}
|
140 |
+
noStyle
|
141 |
+
rules={[{ required: true, message: 'Street is required' }]}
|
142 |
+
>
|
143 |
+
<InputNumber
|
144 |
+
style={{
|
145 |
+
width: 50,
|
146 |
+
}}
|
147 |
+
/>
|
148 |
+
</Form.Item>
|
149 |
+
</Flex>
|
150 |
+
</Form.Item>
|
151 |
+
</section>
|
152 |
+
);
|
153 |
+
};
|
154 |
+
|
155 |
+
export default ModelSetting;
|
web/src/pages/chat/chat-configuration-modal/prompt-engine.tsx
ADDED
@@ -0,0 +1,163 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import { DeleteOutlined } from '@ant-design/icons';
|
2 |
+
import {
|
3 |
+
Button,
|
4 |
+
Col,
|
5 |
+
Divider,
|
6 |
+
Form,
|
7 |
+
Input,
|
8 |
+
Row,
|
9 |
+
Select,
|
10 |
+
Switch,
|
11 |
+
Table,
|
12 |
+
TableProps,
|
13 |
+
} from 'antd';
|
14 |
+
import classNames from 'classnames';
|
15 |
+
import { useState } from 'react';
|
16 |
+
import { v4 as uuid } from 'uuid';
|
17 |
+
import { EditableCell, EditableRow } from './editable-cell';
|
18 |
+
import { ISegmentedContentProps } from './interface';
|
19 |
+
|
20 |
+
import styles from './index.less';
|
21 |
+
|
22 |
+
interface DataType {
|
23 |
+
key: string;
|
24 |
+
optional: boolean;
|
25 |
+
}
|
26 |
+
|
27 |
+
const { Option } = Select;
|
28 |
+
|
29 |
+
const PromptEngine = ({ show }: ISegmentedContentProps) => {
|
30 |
+
const [dataSource, setDataSource] = useState<DataType[]>([]);
|
31 |
+
|
32 |
+
const components = {
|
33 |
+
body: {
|
34 |
+
row: EditableRow,
|
35 |
+
cell: EditableCell,
|
36 |
+
},
|
37 |
+
};
|
38 |
+
|
39 |
+
const handleRemove = (key: string) => () => {
|
40 |
+
const newData = dataSource.filter((item) => item.key !== key);
|
41 |
+
setDataSource(newData);
|
42 |
+
};
|
43 |
+
|
44 |
+
const handleSave = (row: DataType) => {
|
45 |
+
const newData = [...dataSource];
|
46 |
+
const index = newData.findIndex((item) => row.key === item.key);
|
47 |
+
const item = newData[index];
|
48 |
+
newData.splice(index, 1, {
|
49 |
+
...item,
|
50 |
+
...row,
|
51 |
+
});
|
52 |
+
setDataSource(newData);
|
53 |
+
};
|
54 |
+
|
55 |
+
const columns: TableProps<DataType>['columns'] = [
|
56 |
+
{
|
57 |
+
title: 'key',
|
58 |
+
dataIndex: 'variable',
|
59 |
+
key: 'variable',
|
60 |
+
onCell: (record: DataType) => ({
|
61 |
+
record,
|
62 |
+
editable: true,
|
63 |
+
dataIndex: 'variable',
|
64 |
+
title: 'key',
|
65 |
+
handleSave,
|
66 |
+
}),
|
67 |
+
},
|
68 |
+
{
|
69 |
+
title: 'optional',
|
70 |
+
dataIndex: 'optional',
|
71 |
+
key: 'optional',
|
72 |
+
width: 40,
|
73 |
+
align: 'center',
|
74 |
+
render() {
|
75 |
+
return <Switch size="small" />;
|
76 |
+
},
|
77 |
+
},
|
78 |
+
{
|
79 |
+
title: 'operation',
|
80 |
+
dataIndex: 'operation',
|
81 |
+
width: 30,
|
82 |
+
key: 'operation',
|
83 |
+
align: 'center',
|
84 |
+
render(_, record) {
|
85 |
+
return <DeleteOutlined onClick={handleRemove(record.key)} />;
|
86 |
+
},
|
87 |
+
},
|
88 |
+
];
|
89 |
+
|
90 |
+
const handleAdd = () => {
|
91 |
+
setDataSource((state) => [
|
92 |
+
...state,
|
93 |
+
{
|
94 |
+
key: uuid(),
|
95 |
+
variable: '',
|
96 |
+
optional: true,
|
97 |
+
},
|
98 |
+
]);
|
99 |
+
};
|
100 |
+
|
101 |
+
return (
|
102 |
+
<section
|
103 |
+
className={classNames({
|
104 |
+
[styles.segmentedHidden]: !show,
|
105 |
+
})}
|
106 |
+
>
|
107 |
+
<Form.Item
|
108 |
+
label="Orchestrate"
|
109 |
+
name="orchestrate"
|
110 |
+
rules={[{ required: true, message: 'Please input!' }]}
|
111 |
+
>
|
112 |
+
<Input.TextArea autoSize={{ maxRows: 5, minRows: 5 }} />
|
113 |
+
</Form.Item>
|
114 |
+
<Divider></Divider>
|
115 |
+
<section className={classNames(styles.variableContainer)}>
|
116 |
+
<Row align={'middle'} justify="end">
|
117 |
+
<Col span={6} className={styles.variableAlign}>
|
118 |
+
<label className={styles.variableLabel}>Variables</label>
|
119 |
+
</Col>
|
120 |
+
<Col span={18} className={styles.variableAlign}>
|
121 |
+
<Button size="small" onClick={handleAdd}>
|
122 |
+
Add
|
123 |
+
</Button>
|
124 |
+
</Col>
|
125 |
+
</Row>
|
126 |
+
{dataSource.length > 0 && (
|
127 |
+
<Row>
|
128 |
+
<Col span={6}></Col>
|
129 |
+
<Col span={18}>
|
130 |
+
<Table
|
131 |
+
dataSource={dataSource}
|
132 |
+
columns={columns}
|
133 |
+
rowKey={'key'}
|
134 |
+
className={styles.variableTable}
|
135 |
+
components={components}
|
136 |
+
rowClassName={() => styles.editableRow}
|
137 |
+
/>
|
138 |
+
</Col>
|
139 |
+
</Row>
|
140 |
+
)}
|
141 |
+
</section>
|
142 |
+
<Form.Item
|
143 |
+
label="Select one context"
|
144 |
+
name="context"
|
145 |
+
rules={[
|
146 |
+
{
|
147 |
+
required: true,
|
148 |
+
message: 'Please select your favourite colors!',
|
149 |
+
type: 'array',
|
150 |
+
},
|
151 |
+
]}
|
152 |
+
>
|
153 |
+
<Select mode="multiple" placeholder="Please select favourite colors">
|
154 |
+
<Option value="red">Red</Option>
|
155 |
+
<Option value="green">Green</Option>
|
156 |
+
<Option value="blue">Blue</Option>
|
157 |
+
</Select>
|
158 |
+
</Form.Item>
|
159 |
+
</section>
|
160 |
+
);
|
161 |
+
};
|
162 |
+
|
163 |
+
export default PromptEngine;
|
web/src/pages/chat/chat-container/index.less
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
.chatContainer {
|
2 |
+
padding: 0 24px 24px;
|
3 |
+
}
|
web/src/pages/chat/chat-container/index.tsx
ADDED
@@ -0,0 +1,36 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import { Button, Flex, Input } from 'antd';
|
2 |
+
import { ChangeEventHandler, useState } from 'react';
|
3 |
+
|
4 |
+
import styles from './index.less';
|
5 |
+
|
6 |
+
const ChatContainer = () => {
|
7 |
+
const [value, setValue] = useState('');
|
8 |
+
|
9 |
+
const handlePressEnter = () => {
|
10 |
+
console.info(value);
|
11 |
+
};
|
12 |
+
|
13 |
+
const handleInputChange: ChangeEventHandler<HTMLInputElement> = (e) => {
|
14 |
+
setValue(e.target.value);
|
15 |
+
};
|
16 |
+
|
17 |
+
return (
|
18 |
+
<Flex flex={1} className={styles.chatContainer} vertical>
|
19 |
+
<Flex flex={1}>xx</Flex>
|
20 |
+
<Input
|
21 |
+
size="large"
|
22 |
+
placeholder="Message Resume Assistant..."
|
23 |
+
value={value}
|
24 |
+
suffix={
|
25 |
+
<Button type="primary" onClick={handlePressEnter}>
|
26 |
+
Send
|
27 |
+
</Button>
|
28 |
+
}
|
29 |
+
onPressEnter={handlePressEnter}
|
30 |
+
onChange={handleInputChange}
|
31 |
+
/>
|
32 |
+
</Flex>
|
33 |
+
);
|
34 |
+
};
|
35 |
+
|
36 |
+
export default ChatContainer;
|
web/src/pages/chat/index.less
ADDED
@@ -0,0 +1,25 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
.chatWrapper {
|
2 |
+
height: 100%;
|
3 |
+
|
4 |
+
.chatAppWrapper {
|
5 |
+
width: 288px;
|
6 |
+
padding: 26px;
|
7 |
+
}
|
8 |
+
.chatTitleWrapper {
|
9 |
+
width: 220px;
|
10 |
+
padding: 26px 0;
|
11 |
+
}
|
12 |
+
|
13 |
+
.chatTitle {
|
14 |
+
padding: 5px 15px;
|
15 |
+
}
|
16 |
+
|
17 |
+
.chatTitleContent {
|
18 |
+
padding: 5px 10px;
|
19 |
+
}
|
20 |
+
|
21 |
+
.divider {
|
22 |
+
margin: 0;
|
23 |
+
height: 100%;
|
24 |
+
}
|
25 |
+
}
|
web/src/pages/chat/index.tsx
CHANGED
@@ -1,8 +1,64 @@
|
|
|
|
|
|
1 |
import { useSelector } from 'umi';
|
|
|
|
|
|
|
|
|
|
|
2 |
|
3 |
const Chat = () => {
|
4 |
const { name } = useSelector((state: any) => state.chatModel);
|
5 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
6 |
};
|
7 |
|
8 |
export default Chat;
|
|
|
1 |
+
import { FormOutlined } from '@ant-design/icons';
|
2 |
+
import { Button, Card, Divider, Flex, Space, Tag } from 'antd';
|
3 |
import { useSelector } from 'umi';
|
4 |
+
import ChatContainer from './chat-container';
|
5 |
+
|
6 |
+
import ModalManager from '@/components/modal-manager';
|
7 |
+
import ChatConfigurationModal from './chat-configuration-modal';
|
8 |
+
import styles from './index.less';
|
9 |
|
10 |
const Chat = () => {
|
11 |
const { name } = useSelector((state: any) => state.chatModel);
|
12 |
+
|
13 |
+
return (
|
14 |
+
<Flex className={styles.chatWrapper}>
|
15 |
+
<Flex className={styles.chatAppWrapper}>
|
16 |
+
<Flex flex={1} vertical>
|
17 |
+
<ModalManager>
|
18 |
+
{({ visible, showModal, hideModal }) => {
|
19 |
+
return (
|
20 |
+
<>
|
21 |
+
<Button type="primary" onClick={() => showModal()}>
|
22 |
+
Create an Assistant
|
23 |
+
</Button>
|
24 |
+
<ChatConfigurationModal
|
25 |
+
visible={visible}
|
26 |
+
showModal={showModal}
|
27 |
+
hideModal={hideModal}
|
28 |
+
></ChatConfigurationModal>
|
29 |
+
</>
|
30 |
+
);
|
31 |
+
}}
|
32 |
+
</ModalManager>
|
33 |
+
|
34 |
+
<Divider></Divider>
|
35 |
+
<Card>
|
36 |
+
<p>Card content</p>
|
37 |
+
</Card>
|
38 |
+
</Flex>
|
39 |
+
</Flex>
|
40 |
+
<Divider type={'vertical'} className={styles.divider}></Divider>
|
41 |
+
<Flex className={styles.chatTitleWrapper}>
|
42 |
+
<Flex flex={1} vertical>
|
43 |
+
<Flex
|
44 |
+
justify={'space-between'}
|
45 |
+
align="center"
|
46 |
+
className={styles.chatTitle}
|
47 |
+
>
|
48 |
+
<Space>
|
49 |
+
<b>Chat</b>
|
50 |
+
<Tag>25</Tag>
|
51 |
+
</Space>
|
52 |
+
<FormOutlined />
|
53 |
+
</Flex>
|
54 |
+
<Divider></Divider>
|
55 |
+
<section className={styles.chatTitleContent}>today</section>
|
56 |
+
</Flex>
|
57 |
+
</Flex>
|
58 |
+
<Divider type={'vertical'} className={styles.divider}></Divider>
|
59 |
+
<ChatContainer></ChatContainer>
|
60 |
+
</Flex>
|
61 |
+
);
|
62 |
};
|
63 |
|
64 |
export default Chat;
|
web/src/pages/chat/message-box.tsx
ADDED
@@ -0,0 +1,45 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
// RCE CSS
|
2 |
+
import { MessageList } from 'react-chat-elements';
|
3 |
+
import 'react-chat-elements/dist/main.css';
|
4 |
+
|
5 |
+
const ChatBox = () => {
|
6 |
+
return (
|
7 |
+
<div style={{ width: 600 }}>
|
8 |
+
{/* <MessageBox
|
9 |
+
position={'left'}
|
10 |
+
type={'photo'}
|
11 |
+
text={'react.svg'}
|
12 |
+
data={{
|
13 |
+
uri: 'https://facebook.github.io/react/img/logo.svg',
|
14 |
+
status: {
|
15 |
+
click: false,
|
16 |
+
loading: 0,
|
17 |
+
},
|
18 |
+
}}
|
19 |
+
/> */}
|
20 |
+
|
21 |
+
<MessageList
|
22 |
+
// referance={messageListReferance}
|
23 |
+
className="message-list"
|
24 |
+
lockable={true}
|
25 |
+
toBottomHeight={'100%'}
|
26 |
+
dataSource={[
|
27 |
+
{
|
28 |
+
position: 'right',
|
29 |
+
type: 'text',
|
30 |
+
text: 'Lorem ipsum dolor sit amet',
|
31 |
+
date: new Date(),
|
32 |
+
},
|
33 |
+
{
|
34 |
+
position: 'left',
|
35 |
+
type: 'text',
|
36 |
+
text: 'Lorem ipsum dolor sit amet',
|
37 |
+
date: new Date(),
|
38 |
+
},
|
39 |
+
]}
|
40 |
+
/>
|
41 |
+
</div>
|
42 |
+
);
|
43 |
+
};
|
44 |
+
|
45 |
+
export default ChatBox;
|
web/src/pages/knowledge/knowledge-card/index.less
CHANGED
@@ -26,7 +26,7 @@
|
|
26 |
border: 1px solid rgba(234, 236, 240, 1);
|
27 |
box-shadow: 0px 1px 2px 0px rgba(16, 24, 40, 0.05);
|
28 |
padding: 24px;
|
29 |
-
|
30 |
cursor: pointer;
|
31 |
|
32 |
.titleWrapper {
|
|
|
26 |
border: 1px solid rgba(234, 236, 240, 1);
|
27 |
box-shadow: 0px 1px 2px 0px rgba(16, 24, 40, 0.05);
|
28 |
padding: 24px;
|
29 |
+
width: 300px;
|
30 |
cursor: pointer;
|
31 |
|
32 |
.titleWrapper {
|
web/src/pages/knowledge/knowledge-card/index.tsx
CHANGED
@@ -63,7 +63,7 @@ const KnowledgeCard = ({ item }: IProps) => {
|
|
63 |
<Card className={styles.card} onClick={handleCardClick}>
|
64 |
<div className={styles.container}>
|
65 |
<div className={styles.content}>
|
66 |
-
<Avatar size={34} icon={<UserOutlined />} />
|
67 |
|
68 |
<span className={styles.delete}>
|
69 |
<Dropdown
|
@@ -78,14 +78,14 @@ const KnowledgeCard = ({ item }: IProps) => {
|
|
78 |
</div>
|
79 |
<div className={styles.titleWrapper}>
|
80 |
<span className={styles.title}>{item.name}</span>
|
81 |
-
<p>
|
82 |
</div>
|
83 |
<div className={styles.footer}>
|
84 |
<div className={styles.footerTop}>
|
85 |
<div className={styles.bottomLeft}>
|
86 |
<FileTextOutlined className={styles.leftIcon} />
|
87 |
<span className={styles.rightText}>
|
88 |
-
<Space>{item.doc_num}
|
89 |
</span>
|
90 |
</div>
|
91 |
</div>
|
|
|
63 |
<Card className={styles.card} onClick={handleCardClick}>
|
64 |
<div className={styles.container}>
|
65 |
<div className={styles.content}>
|
66 |
+
<Avatar size={34} icon={<UserOutlined />} src={item.avatar} />
|
67 |
|
68 |
<span className={styles.delete}>
|
69 |
<Dropdown
|
|
|
78 |
</div>
|
79 |
<div className={styles.titleWrapper}>
|
80 |
<span className={styles.title}>{item.name}</span>
|
81 |
+
<p>{item.description}</p>
|
82 |
</div>
|
83 |
<div className={styles.footer}>
|
84 |
<div className={styles.footerTop}>
|
85 |
<div className={styles.bottomLeft}>
|
86 |
<FileTextOutlined className={styles.leftIcon} />
|
87 |
<span className={styles.rightText}>
|
88 |
+
<Space>{item.doc_num}Docs</Space>
|
89 |
</span>
|
90 |
</div>
|
91 |
</div>
|