@lobehub/chat 0.55.1 → 0.57.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +71 -0
- package/package.json +3 -3
- package/src/const/fetch.ts +2 -0
- package/src/const/plugin.ts +1 -0
- package/src/features/AgentSetting/AgentPlugin/index.tsx +107 -60
- package/src/features/PluginSettings/PluginSettingRender.tsx +65 -0
- package/src/features/PluginSettings/index.tsx +65 -0
- package/src/hooks/useImportConfig.ts +7 -0
- package/src/locales/default/error.ts +30 -2
- package/src/locales/default/plugin.ts +1 -1
- package/src/locales/default/setting.ts +1 -0
- package/src/pages/api/auth.ts +2 -2
- package/src/pages/api/error.ts +3 -3
- package/src/pages/api/openai.ts +3 -3
- package/src/pages/chat/SessionList/List/Item/index.tsx +2 -2
- package/src/pages/chat/features/Conversation/ChatList/Error/Plugin/PluginError.tsx +28 -0
- package/src/pages/chat/features/Conversation/ChatList/Error/Plugin/PluginSettings.tsx +61 -0
- package/src/pages/chat/features/Conversation/ChatList/Error/index.tsx +42 -0
- package/src/pages/chat/features/Conversation/ChatList/Plugins/FunctionCall.tsx +62 -58
- package/src/pages/chat/features/Conversation/ChatList/index.tsx +15 -25
- package/src/pages/chat/features/Header/PluginTag.tsx +1 -1
- package/src/services/plugin.ts +11 -14
- package/src/services/pluginMarket.ts +10 -0
- package/src/store/global/selectors.ts +2 -2
- package/src/store/global/store.ts +7 -0
- package/src/store/plugin/action.ts +18 -7
- package/src/store/plugin/initialState.ts +3 -0
- package/src/store/plugin/reducers/manifest.ts +2 -2
- package/src/store/plugin/selectors.ts +17 -5
- package/src/store/plugin/store.ts +3 -1
- package/src/store/session/slices/chat/actions/message.ts +30 -21
- package/src/store/session/slices/chat/selectors/utils.test.ts +4 -2
- package/src/store/session/slices/chat/selectors/utils.ts +2 -2
- package/src/types/chatMessage.ts +9 -0
- package/src/types/fetch.ts +18 -14
- package/src/types/plugin.ts +2 -2
- package/src/utils/fetch.ts +24 -18
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,77 @@
|
|
|
2
2
|
|
|
3
3
|
# Changelog
|
|
4
4
|
|
|
5
|
+
## [Version 0.57.0](https://github.com/lobehub/lobe-chat/compare/v0.56.0...v0.57.0)
|
|
6
|
+
|
|
7
|
+
<sup>Released on **2023-08-26**</sup>
|
|
8
|
+
|
|
9
|
+
#### ♻ Code Refactoring
|
|
10
|
+
|
|
11
|
+
- **misc**: Refactor to ChatErrorType.
|
|
12
|
+
|
|
13
|
+
#### ✨ Features
|
|
14
|
+
|
|
15
|
+
- **misc**: 完善插件请求的错误处理, 支持修改与记录插件的配置, 支持发送插件配置信息, 支持渲染 manifest 中的 settings, 支持设置不正确时进行插件的配置, 新增插件请求状态的错误处理.
|
|
16
|
+
|
|
17
|
+
#### 🐛 Bug Fixes
|
|
18
|
+
|
|
19
|
+
- **misc**: 修正缓存旧数据的报错问题.
|
|
20
|
+
|
|
21
|
+
<br/>
|
|
22
|
+
|
|
23
|
+
<details>
|
|
24
|
+
<summary><kbd>Improvements and Fixes</kbd></summary>
|
|
25
|
+
|
|
26
|
+
#### Code refactoring
|
|
27
|
+
|
|
28
|
+
- **misc**: Refactor to ChatErrorType ([cd1a033](https://github.com/lobehub/lobe-chat/commit/cd1a033))
|
|
29
|
+
|
|
30
|
+
#### What's improved
|
|
31
|
+
|
|
32
|
+
- **misc**: 完善插件请求的错误处理 ([0698d89](https://github.com/lobehub/lobe-chat/commit/0698d89))
|
|
33
|
+
- **misc**: 支持修改与记录插件的配置 ([76e8237](https://github.com/lobehub/lobe-chat/commit/76e8237))
|
|
34
|
+
- **misc**: 支持发送插件配置信息 ([2cedc85](https://github.com/lobehub/lobe-chat/commit/2cedc85))
|
|
35
|
+
- **misc**: 支持渲染 manifest 中的 settings ([1185300](https://github.com/lobehub/lobe-chat/commit/1185300))
|
|
36
|
+
- **misc**: 支持设置不正确时进行插件的配置 ([f972481](https://github.com/lobehub/lobe-chat/commit/f972481))
|
|
37
|
+
- **misc**: 新增插件请求状态的错误处理 ([228002a](https://github.com/lobehub/lobe-chat/commit/228002a))
|
|
38
|
+
|
|
39
|
+
#### What's fixed
|
|
40
|
+
|
|
41
|
+
- **misc**: 修正缓存旧数据的报错问题 ([5d8008f](https://github.com/lobehub/lobe-chat/commit/5d8008f))
|
|
42
|
+
|
|
43
|
+
</details>
|
|
44
|
+
|
|
45
|
+
<div align="right">
|
|
46
|
+
|
|
47
|
+
[](#readme-top)
|
|
48
|
+
|
|
49
|
+
</div>
|
|
50
|
+
|
|
51
|
+
## [Version 0.56.0](https://github.com/lobehub/lobe-chat/compare/v0.55.1...v0.56.0)
|
|
52
|
+
|
|
53
|
+
<sup>Released on **2023-08-24**</sup>
|
|
54
|
+
|
|
55
|
+
#### ✨ Features
|
|
56
|
+
|
|
57
|
+
- **misc**: Use new plugin manifest to support plugin’s multi api.
|
|
58
|
+
|
|
59
|
+
<br/>
|
|
60
|
+
|
|
61
|
+
<details>
|
|
62
|
+
<summary><kbd>Improvements and Fixes</kbd></summary>
|
|
63
|
+
|
|
64
|
+
#### What's improved
|
|
65
|
+
|
|
66
|
+
- **misc**: Use new plugin manifest to support plugin’s multi api, closes [#101](https://github.com/lobehub/lobe-chat/issues/101) ([4534598](https://github.com/lobehub/lobe-chat/commit/4534598))
|
|
67
|
+
|
|
68
|
+
</details>
|
|
69
|
+
|
|
70
|
+
<div align="right">
|
|
71
|
+
|
|
72
|
+
[](#readme-top)
|
|
73
|
+
|
|
74
|
+
</div>
|
|
75
|
+
|
|
5
76
|
### [Version 0.55.1](https://github.com/lobehub/lobe-chat/compare/v0.55.0...v0.55.1)
|
|
6
77
|
|
|
7
78
|
<sup>Released on **2023-08-22**</sup>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lobehub/chat",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.57.0",
|
|
4
4
|
"description": "Lobe Chat is an open-source chatbot client using LangChain, Typescript and Next.js",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"chatbot",
|
|
@@ -68,7 +68,7 @@
|
|
|
68
68
|
"@emoji-mart/react": "^1",
|
|
69
69
|
"@icons-pack/react-simple-icons": "^8",
|
|
70
70
|
"@lobehub/chat-plugin-sdk": "latest",
|
|
71
|
-
"@lobehub/chat-plugins-gateway": "
|
|
71
|
+
"@lobehub/chat-plugins-gateway": "latest",
|
|
72
72
|
"@lobehub/ui": "latest",
|
|
73
73
|
"@vercel/analytics": "^1",
|
|
74
74
|
"ahooks": "^3",
|
|
@@ -130,7 +130,7 @@
|
|
|
130
130
|
"lint-staged": "^14",
|
|
131
131
|
"next-pwa": "^5",
|
|
132
132
|
"node-fetch": "^3",
|
|
133
|
-
"prettier": "^
|
|
133
|
+
"prettier": "^3",
|
|
134
134
|
"remark": "^14",
|
|
135
135
|
"remark-cli": "^11",
|
|
136
136
|
"semantic-release": "^21",
|
package/src/const/fetch.ts
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const PLUGIN_SCHEMA_SEPARATOR = '--__--';
|
|
@@ -1,17 +1,20 @@
|
|
|
1
|
-
import { Avatar, Form, ItemGroup } from '@lobehub/ui';
|
|
1
|
+
import { Avatar, Form, ItemGroup, Markdown } from '@lobehub/ui';
|
|
2
2
|
import { Skeleton, Switch } from 'antd';
|
|
3
3
|
import { createStyles } from 'antd-style';
|
|
4
4
|
import isEqual from 'fast-deep-equal';
|
|
5
|
-
import { ToyBrick } from 'lucide-react';
|
|
6
|
-
import { memo
|
|
5
|
+
import { LucideStore, ToyBrick } from 'lucide-react';
|
|
6
|
+
import { memo } from 'react';
|
|
7
7
|
import { useTranslation } from 'react-i18next';
|
|
8
8
|
|
|
9
9
|
import { FORM_STYLE } from '@/const/layoutTokens';
|
|
10
|
+
import { transformPluginSettings } from '@/features/PluginSettings';
|
|
11
|
+
import PluginSettingRender from '@/features/PluginSettings/PluginSettingRender';
|
|
10
12
|
import { usePluginStore } from '@/store/plugin';
|
|
11
|
-
import {
|
|
13
|
+
import { useSessionStore } from '@/store/session';
|
|
14
|
+
import { AgentAction, agentSelectors } from '@/store/session/slices/agentConfig';
|
|
12
15
|
import { LobeAgentConfig } from '@/types/session';
|
|
13
16
|
|
|
14
|
-
const useStyles = createStyles(({ css }) => ({
|
|
17
|
+
const useStyles = createStyles(({ css, token }) => ({
|
|
15
18
|
avatar: css`
|
|
16
19
|
.ant-skeleton-header {
|
|
17
20
|
padding-right: 0;
|
|
@@ -26,6 +29,11 @@ const useStyles = createStyles(({ css }) => ({
|
|
|
26
29
|
margin-block-start: 12px !important;
|
|
27
30
|
}
|
|
28
31
|
`,
|
|
32
|
+
md: css`
|
|
33
|
+
p {
|
|
34
|
+
color: ${token.colorTextDescription};
|
|
35
|
+
}
|
|
36
|
+
`,
|
|
29
37
|
}));
|
|
30
38
|
|
|
31
39
|
export interface AgentPluginProps {
|
|
@@ -36,72 +44,111 @@ export interface AgentPluginProps {
|
|
|
36
44
|
const AgentPlugin = memo<AgentPluginProps>(({ config, updateConfig }) => {
|
|
37
45
|
const { t } = useTranslation('setting');
|
|
38
46
|
const { styles } = useStyles();
|
|
39
|
-
const [useFetchPluginList, fetchPluginManifest] = usePluginStore((s) => [
|
|
47
|
+
const [useFetchPluginList, fetchPluginManifest, updatePluginSettings] = usePluginStore((s) => [
|
|
40
48
|
s.useFetchPluginList,
|
|
41
49
|
s.fetchPluginManifest,
|
|
50
|
+
s.updatePluginSettings,
|
|
42
51
|
]);
|
|
43
52
|
const pluginManifestLoading = usePluginStore((s) => s.pluginManifestLoading, isEqual);
|
|
53
|
+
const pluginManifestMap = usePluginStore((s) => s.pluginManifestMap, isEqual);
|
|
54
|
+
const pluginsSettings = usePluginStore((s) => s.pluginsSettings, isEqual);
|
|
44
55
|
const { data } = useFetchPluginList();
|
|
45
56
|
|
|
46
|
-
const
|
|
47
|
-
let children;
|
|
57
|
+
const plugins = useSessionStore(agentSelectors.currentAgentPlugins);
|
|
48
58
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
59
|
+
const loadingItem = {
|
|
60
|
+
avatar: (
|
|
61
|
+
<Skeleton
|
|
62
|
+
active
|
|
63
|
+
avatar={{ size: 40 }}
|
|
64
|
+
className={styles.avatar}
|
|
65
|
+
paragraph={false}
|
|
66
|
+
title={false}
|
|
67
|
+
/>
|
|
68
|
+
),
|
|
69
|
+
label: (
|
|
70
|
+
<Skeleton
|
|
71
|
+
active
|
|
72
|
+
avatar={false}
|
|
73
|
+
paragraph={{ className: styles.label, style: { marginBottom: 0 } }}
|
|
74
|
+
style={{ width: 300 }}
|
|
75
|
+
title={false}
|
|
76
|
+
/>
|
|
77
|
+
),
|
|
78
|
+
};
|
|
69
79
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
80
|
+
const children = !data
|
|
81
|
+
? [loadingItem, loadingItem, loadingItem]
|
|
82
|
+
: data.plugins.map(({ identifier, meta }) => ({
|
|
83
|
+
avatar: <Avatar avatar={meta.avatar} />,
|
|
84
|
+
children: (
|
|
85
|
+
<Switch
|
|
86
|
+
checked={
|
|
87
|
+
// 如果在加载中,说明激活了
|
|
88
|
+
pluginManifestLoading[identifier] || !config.plugins
|
|
89
|
+
? false
|
|
90
|
+
: config.plugins.includes(identifier)
|
|
91
|
+
}
|
|
92
|
+
loading={pluginManifestLoading[identifier]}
|
|
93
|
+
onChange={(checked) => {
|
|
94
|
+
updateConfig(identifier, checked);
|
|
95
|
+
if (checked) {
|
|
96
|
+
fetchPluginManifest(identifier);
|
|
81
97
|
}
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
98
|
+
}}
|
|
99
|
+
/>
|
|
100
|
+
),
|
|
101
|
+
desc: meta?.description,
|
|
102
|
+
label: meta.title,
|
|
103
|
+
minWidth: undefined,
|
|
104
|
+
tag: identifier,
|
|
105
|
+
}));
|
|
106
|
+
|
|
107
|
+
const pluginsConfig = !data
|
|
108
|
+
? []
|
|
109
|
+
: (plugins
|
|
110
|
+
.map((identifier) => {
|
|
111
|
+
const item = data.plugins.find((i) => i.identifier === identifier);
|
|
112
|
+
|
|
113
|
+
if (!item) return null;
|
|
114
|
+
const manifest = pluginManifestMap[identifier];
|
|
115
|
+
|
|
116
|
+
if (!manifest.settings) return null;
|
|
96
117
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
118
|
+
return {
|
|
119
|
+
children: transformPluginSettings(manifest.settings).map((item) => ({
|
|
120
|
+
...item,
|
|
121
|
+
children: (
|
|
122
|
+
<PluginSettingRender
|
|
123
|
+
defaultValue={pluginsSettings[identifier]?.[item.name]}
|
|
124
|
+
format={item.format}
|
|
125
|
+
onChange={(value) => {
|
|
126
|
+
updatePluginSettings(identifier, { [item.name]: value });
|
|
127
|
+
}}
|
|
128
|
+
type={item.type as any}
|
|
129
|
+
/>
|
|
130
|
+
),
|
|
131
|
+
desc: item.desc && <Markdown className={styles.md}>{item.desc}</Markdown>,
|
|
132
|
+
})),
|
|
133
|
+
icon: ToyBrick,
|
|
134
|
+
title: t('settingPlugin.config', { id: item.meta.title || item.identifier }),
|
|
135
|
+
};
|
|
136
|
+
})
|
|
137
|
+
.filter(Boolean) as unknown as ItemGroup[]);
|
|
103
138
|
|
|
104
|
-
return
|
|
139
|
+
return (
|
|
140
|
+
<Form
|
|
141
|
+
items={[
|
|
142
|
+
{
|
|
143
|
+
children,
|
|
144
|
+
icon: LucideStore,
|
|
145
|
+
title: t('settingPlugin.title'),
|
|
146
|
+
},
|
|
147
|
+
...pluginsConfig,
|
|
148
|
+
]}
|
|
149
|
+
{...FORM_STYLE}
|
|
150
|
+
/>
|
|
151
|
+
);
|
|
105
152
|
});
|
|
106
153
|
|
|
107
154
|
export default AgentPlugin;
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { Input, InputNumber, Switch } from 'antd';
|
|
2
|
+
import { memo } from 'react';
|
|
3
|
+
|
|
4
|
+
interface PluginSettingsProps {
|
|
5
|
+
defaultValue?: any;
|
|
6
|
+
format?: string;
|
|
7
|
+
onChange: (value: any) => void;
|
|
8
|
+
props?: any;
|
|
9
|
+
type?: 'string' | 'number' | 'boolean';
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const PluginSettingRender = memo<PluginSettingsProps>(
|
|
13
|
+
({ type, defaultValue, onChange, format, props }) => {
|
|
14
|
+
switch (type) {
|
|
15
|
+
case 'string': {
|
|
16
|
+
switch (format) {
|
|
17
|
+
case 'password': {
|
|
18
|
+
return (
|
|
19
|
+
<Input.Password
|
|
20
|
+
{...props}
|
|
21
|
+
defaultValue={defaultValue}
|
|
22
|
+
onChange={(v) => {
|
|
23
|
+
onChange(v.target.value);
|
|
24
|
+
}}
|
|
25
|
+
/>
|
|
26
|
+
);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
return (
|
|
30
|
+
<Input
|
|
31
|
+
{...props}
|
|
32
|
+
defaultValue={defaultValue}
|
|
33
|
+
onChange={(v) => {
|
|
34
|
+
onChange(v.target.value);
|
|
35
|
+
}}
|
|
36
|
+
/>
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
case 'number': {
|
|
40
|
+
return (
|
|
41
|
+
<InputNumber
|
|
42
|
+
{...props}
|
|
43
|
+
defaultValue={defaultValue}
|
|
44
|
+
onChange={(v) => {
|
|
45
|
+
onChange(v);
|
|
46
|
+
}}
|
|
47
|
+
/>
|
|
48
|
+
);
|
|
49
|
+
}
|
|
50
|
+
case 'boolean': {
|
|
51
|
+
return (
|
|
52
|
+
<Switch
|
|
53
|
+
{...props}
|
|
54
|
+
defaultValue={defaultValue}
|
|
55
|
+
onChange={(e) => {
|
|
56
|
+
onChange(e);
|
|
57
|
+
}}
|
|
58
|
+
/>
|
|
59
|
+
);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
},
|
|
63
|
+
);
|
|
64
|
+
|
|
65
|
+
export default PluginSettingRender;
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { PluginSchema } from '@lobehub/chat-plugin-sdk';
|
|
2
|
+
import { Form, Markdown } from '@lobehub/ui';
|
|
3
|
+
import { createStyles } from 'antd-style';
|
|
4
|
+
import isEqual from 'fast-deep-equal';
|
|
5
|
+
import { memo } from 'react';
|
|
6
|
+
|
|
7
|
+
import { usePluginStore } from '@/store/plugin';
|
|
8
|
+
|
|
9
|
+
import PluginSettingRender from './PluginSettingRender';
|
|
10
|
+
|
|
11
|
+
export const transformPluginSettings = (pluginSettings: PluginSchema) => {
|
|
12
|
+
return Object.entries(pluginSettings.properties).map(([name, i]) => ({
|
|
13
|
+
desc: i.description,
|
|
14
|
+
format: i.format,
|
|
15
|
+
label: i.title,
|
|
16
|
+
name,
|
|
17
|
+
tag: name,
|
|
18
|
+
type: i.type,
|
|
19
|
+
}));
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
interface PluginSettingsConfigProps {
|
|
23
|
+
id: string;
|
|
24
|
+
settings: PluginSchema;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const useStyles = createStyles(({ css, token }) => ({
|
|
28
|
+
md: css`
|
|
29
|
+
p {
|
|
30
|
+
color: ${token.colorTextDescription};
|
|
31
|
+
}
|
|
32
|
+
`,
|
|
33
|
+
}));
|
|
34
|
+
|
|
35
|
+
const PluginSettingsConfig = memo<PluginSettingsConfigProps>(({ settings, id }) => {
|
|
36
|
+
const items = transformPluginSettings(settings);
|
|
37
|
+
|
|
38
|
+
const { styles } = useStyles();
|
|
39
|
+
const [updatePluginSettings] = usePluginStore((s) => [s.updatePluginSettings]);
|
|
40
|
+
const pluginSetting = usePluginStore((s) => s.pluginsSettings[id] || {}, isEqual);
|
|
41
|
+
|
|
42
|
+
return (
|
|
43
|
+
<Form layout={'vertical'}>
|
|
44
|
+
{items.map((item) => (
|
|
45
|
+
<Form.Item
|
|
46
|
+
desc={item.desc && <Markdown className={styles.md}>{item.desc as string}</Markdown>}
|
|
47
|
+
key={item.label}
|
|
48
|
+
label={item.label}
|
|
49
|
+
tag={item.tag}
|
|
50
|
+
>
|
|
51
|
+
<PluginSettingRender
|
|
52
|
+
defaultValue={pluginSetting[item.name]}
|
|
53
|
+
format={item.format}
|
|
54
|
+
onChange={(value) => {
|
|
55
|
+
updatePluginSettings(id, { [item.name]: value });
|
|
56
|
+
}}
|
|
57
|
+
type={item.type as any}
|
|
58
|
+
/>
|
|
59
|
+
</Form.Item>
|
|
60
|
+
))}
|
|
61
|
+
</Form>
|
|
62
|
+
);
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
export default PluginSettingsConfig;
|
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
import { useMemo } from 'react';
|
|
2
2
|
|
|
3
3
|
import { useGlobalStore } from '@/store/global';
|
|
4
|
+
import { usePluginStore } from '@/store/plugin';
|
|
4
5
|
import { useSessionStore } from '@/store/session';
|
|
5
6
|
import { importConfigFile } from '@/utils/config';
|
|
6
7
|
|
|
7
8
|
export const useImportConfig = () => {
|
|
8
9
|
const importSessions = useSessionStore((s) => s.importSessions);
|
|
9
10
|
const importAppSettings = useGlobalStore((s) => s.importAppSettings);
|
|
11
|
+
const checkLocalEnabledPlugins = usePluginStore((s) => s.checkLocalEnabledPlugins);
|
|
10
12
|
|
|
11
13
|
const importConfig = (info: any) => {
|
|
12
14
|
importConfigFile(info, (config) => {
|
|
@@ -19,6 +21,9 @@ export const useImportConfig = () => {
|
|
|
19
21
|
case 'sessions':
|
|
20
22
|
case 'agents': {
|
|
21
23
|
importSessions(config.state.sessions);
|
|
24
|
+
|
|
25
|
+
// 检查一下插件开启情况
|
|
26
|
+
checkLocalEnabledPlugins(config.state.sessions);
|
|
22
27
|
break;
|
|
23
28
|
}
|
|
24
29
|
|
|
@@ -26,6 +31,8 @@ export const useImportConfig = () => {
|
|
|
26
31
|
importSessions(config.state.sessions);
|
|
27
32
|
importAppSettings(config.state.settings);
|
|
28
33
|
|
|
34
|
+
// 检查一下插件开启情况
|
|
35
|
+
checkLocalEnabledPlugins(config.state.sessions);
|
|
29
36
|
break;
|
|
30
37
|
}
|
|
31
38
|
}
|
|
@@ -1,4 +1,12 @@
|
|
|
1
|
+
import { PluginErrorType } from '@lobehub/chat-plugin-sdk';
|
|
2
|
+
|
|
3
|
+
import { ChatErrorType } from '@/types/fetch';
|
|
4
|
+
|
|
1
5
|
export default {
|
|
6
|
+
pluginSettings: {
|
|
7
|
+
desc: '完成以下配置,即可开始使用该插件',
|
|
8
|
+
title: '{{name}}插件配置',
|
|
9
|
+
},
|
|
2
10
|
response: {
|
|
3
11
|
400: '很抱歉,服务器不明白您的请求,请确认您的请求参数是否正确',
|
|
4
12
|
401: '很抱歉,服务器拒绝了您的请求,可能是因为您的权限不足或未提供有效的身份验证',
|
|
@@ -11,8 +19,28 @@ export default {
|
|
|
11
19
|
503: '很抱歉,服务器当前无法处理您的请求,可能是由于过载或正在进行维护,请稍后再试',
|
|
12
20
|
504: '很抱歉,服务器没有等到上游服务器的回应,请稍后再试',
|
|
13
21
|
|
|
14
|
-
|
|
15
|
-
|
|
22
|
+
[PluginErrorType.PluginMarketIndexNotFound]:
|
|
23
|
+
'很抱歉,服务器没有找到插件索引,请检查索引地址是否正确',
|
|
24
|
+
[PluginErrorType.PluginMarketIndexInvalid]:
|
|
25
|
+
'很抱歉,插件索引校验未通过,请检查索引文件格式是否规范',
|
|
26
|
+
[PluginErrorType.PluginMetaNotFound]:
|
|
27
|
+
'很抱歉,没有在索引中发现该插件,请插件在索引中的配置信息',
|
|
28
|
+
[PluginErrorType.PluginMetaInvalid]:
|
|
29
|
+
'很抱歉,该插件的元信息校验未通过,请检查插件元信息格式是否规范',
|
|
30
|
+
[PluginErrorType.PluginManifestNotFound]:
|
|
31
|
+
'很抱歉,服务器没有找到该插件的描述清单 (manifest.json),请检查插件描述文件地址是否正确',
|
|
32
|
+
[PluginErrorType.PluginManifestInvalid]:
|
|
33
|
+
'很抱歉,该插件的描述清单校验未通过,请检查描述清单格式是否规范',
|
|
34
|
+
[PluginErrorType.PluginApiNotFound]:
|
|
35
|
+
'很抱歉,插件描述清单中不存在该 API ,请检查你的请求方法与插件清单 API 是否匹配',
|
|
36
|
+
[PluginErrorType.PluginApiParamsError]:
|
|
37
|
+
'很抱歉,该插件请求的入参校验未通过,请检查入参与 Api 描述信息是否匹配',
|
|
38
|
+
[PluginErrorType.PluginSettingsInvalid]:
|
|
39
|
+
'很抱歉,该插件需要正确配置后才可以使用,请检查你的配置是否正确',
|
|
40
|
+
|
|
41
|
+
[ChatErrorType.InvalidAccessCode]:
|
|
42
|
+
'密码不正确或为空,请输入正确的访问密码,或者添加自定义 OpenAI API Key',
|
|
43
|
+
[ChatErrorType.OpenAIBizError]: '请求 OpenAI 服务出错,请根据以下信息排查或重试',
|
|
16
44
|
},
|
|
17
45
|
unlock: {
|
|
18
46
|
apikey: {
|
package/src/pages/api/auth.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { getServerConfig } from '@/config/server';
|
|
2
|
-
import {
|
|
2
|
+
import { ChatErrorType } from '@/types/fetch';
|
|
3
3
|
|
|
4
4
|
interface AuthConfig {
|
|
5
5
|
accessCode?: string | null;
|
|
@@ -18,7 +18,7 @@ export const checkAuth = ({ apiKey, accessCode }: AuthConfig) => {
|
|
|
18
18
|
if (!ACCESS_CODE) return { auth: true };
|
|
19
19
|
|
|
20
20
|
if (accessCode !== ACCESS_CODE) {
|
|
21
|
-
return { auth: false, error:
|
|
21
|
+
return { auth: false, error: ChatErrorType.InvalidAccessCode };
|
|
22
22
|
}
|
|
23
23
|
|
|
24
24
|
return { auth: true };
|
package/src/pages/api/error.ts
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import { ErrorResponse, ErrorType } from '@/types/fetch';
|
|
1
|
+
import { ChatErrorType, ErrorResponse, ErrorType } from '@/types/fetch';
|
|
2
2
|
|
|
3
3
|
const getStatus = (errorType: ErrorType) => {
|
|
4
4
|
switch (errorType) {
|
|
5
|
-
case
|
|
5
|
+
case ChatErrorType.InvalidAccessCode: {
|
|
6
6
|
return 401;
|
|
7
7
|
}
|
|
8
8
|
|
|
9
|
-
case
|
|
9
|
+
case ChatErrorType.OpenAIBizError: {
|
|
10
10
|
return 577;
|
|
11
11
|
}
|
|
12
12
|
}
|
package/src/pages/api/openai.ts
CHANGED
|
@@ -3,7 +3,7 @@ import { Configuration, OpenAIApi } from 'openai-edge';
|
|
|
3
3
|
|
|
4
4
|
import { getServerConfig } from '@/config/server';
|
|
5
5
|
import { createErrorResponse } from '@/pages/api/error';
|
|
6
|
-
import {
|
|
6
|
+
import { ChatErrorType } from '@/types/fetch';
|
|
7
7
|
import { OpenAIStreamPayload } from '@/types/openai';
|
|
8
8
|
|
|
9
9
|
// 创建 OpenAI 实例
|
|
@@ -55,7 +55,7 @@ export const createChatCompletion = async ({
|
|
|
55
55
|
response = await openai.createChatCompletion(requestParams);
|
|
56
56
|
} catch (error) {
|
|
57
57
|
// 如果 await 超时报错,说明是 OpenAI 服务端的问题
|
|
58
|
-
return createErrorResponse(
|
|
58
|
+
return createErrorResponse(ChatErrorType.GatewayTimeout, { message: error });
|
|
59
59
|
}
|
|
60
60
|
|
|
61
61
|
// ============ 4. 处理异常响应 ============ //
|
|
@@ -72,7 +72,7 @@ export const createChatCompletion = async ({
|
|
|
72
72
|
error = { message: result };
|
|
73
73
|
}
|
|
74
74
|
|
|
75
|
-
return createErrorResponse(
|
|
75
|
+
return createErrorResponse(ChatErrorType.OpenAIBizError, { ...error, endpoint });
|
|
76
76
|
}
|
|
77
77
|
|
|
78
78
|
// ============ 5. 发送正常相应 ============ //
|
|
@@ -6,7 +6,7 @@ import { memo, useMemo, useRef, useState } from 'react';
|
|
|
6
6
|
import { Flexbox } from 'react-layout-kit';
|
|
7
7
|
import { shallow } from 'zustand/shallow';
|
|
8
8
|
|
|
9
|
-
import { useGlobalStore } from '@/store/global';
|
|
9
|
+
import { settingsSelectors, useGlobalStore } from '@/store/global';
|
|
10
10
|
import { agentSelectors, sessionSelectors, useSessionStore } from '@/store/session';
|
|
11
11
|
|
|
12
12
|
import Actions from './Actions';
|
|
@@ -35,7 +35,7 @@ const SessionItem = memo<SessionItemProps>(({ id }) => {
|
|
|
35
35
|
const isHovering = useHover(ref);
|
|
36
36
|
|
|
37
37
|
const { styles } = useStyles();
|
|
38
|
-
const [defaultModel] = useGlobalStore((s) => [s.
|
|
38
|
+
const [defaultModel] = useGlobalStore((s) => [settingsSelectors.currentAgentConfig(s).model]);
|
|
39
39
|
|
|
40
40
|
const [
|
|
41
41
|
active,
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { Highlighter } from '@lobehub/ui';
|
|
2
|
+
import { memo } from 'react';
|
|
3
|
+
import { Flexbox } from 'react-layout-kit';
|
|
4
|
+
|
|
5
|
+
import { useStyles } from '../style';
|
|
6
|
+
|
|
7
|
+
interface OpenAIError {
|
|
8
|
+
code: 'invalid_api_key' | string;
|
|
9
|
+
message: string;
|
|
10
|
+
param?: any;
|
|
11
|
+
type: string;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
interface OpenAIErrorResponse {
|
|
15
|
+
error: OpenAIError;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const PluginError = memo<{ content: OpenAIErrorResponse; id: string }>(({ content }) => {
|
|
19
|
+
const { styles } = useStyles();
|
|
20
|
+
|
|
21
|
+
return (
|
|
22
|
+
<Flexbox className={styles.container} style={{ maxWidth: 600 }}>
|
|
23
|
+
<Highlighter language={'json'}>{JSON.stringify(content, null, 2)}</Highlighter>
|
|
24
|
+
</Flexbox>
|
|
25
|
+
);
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
export default PluginError;
|