@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.
Files changed (37) hide show
  1. package/CHANGELOG.md +71 -0
  2. package/package.json +3 -3
  3. package/src/const/fetch.ts +2 -0
  4. package/src/const/plugin.ts +1 -0
  5. package/src/features/AgentSetting/AgentPlugin/index.tsx +107 -60
  6. package/src/features/PluginSettings/PluginSettingRender.tsx +65 -0
  7. package/src/features/PluginSettings/index.tsx +65 -0
  8. package/src/hooks/useImportConfig.ts +7 -0
  9. package/src/locales/default/error.ts +30 -2
  10. package/src/locales/default/plugin.ts +1 -1
  11. package/src/locales/default/setting.ts +1 -0
  12. package/src/pages/api/auth.ts +2 -2
  13. package/src/pages/api/error.ts +3 -3
  14. package/src/pages/api/openai.ts +3 -3
  15. package/src/pages/chat/SessionList/List/Item/index.tsx +2 -2
  16. package/src/pages/chat/features/Conversation/ChatList/Error/Plugin/PluginError.tsx +28 -0
  17. package/src/pages/chat/features/Conversation/ChatList/Error/Plugin/PluginSettings.tsx +61 -0
  18. package/src/pages/chat/features/Conversation/ChatList/Error/index.tsx +42 -0
  19. package/src/pages/chat/features/Conversation/ChatList/Plugins/FunctionCall.tsx +62 -58
  20. package/src/pages/chat/features/Conversation/ChatList/index.tsx +15 -25
  21. package/src/pages/chat/features/Header/PluginTag.tsx +1 -1
  22. package/src/services/plugin.ts +11 -14
  23. package/src/services/pluginMarket.ts +10 -0
  24. package/src/store/global/selectors.ts +2 -2
  25. package/src/store/global/store.ts +7 -0
  26. package/src/store/plugin/action.ts +18 -7
  27. package/src/store/plugin/initialState.ts +3 -0
  28. package/src/store/plugin/reducers/manifest.ts +2 -2
  29. package/src/store/plugin/selectors.ts +17 -5
  30. package/src/store/plugin/store.ts +3 -1
  31. package/src/store/session/slices/chat/actions/message.ts +30 -21
  32. package/src/store/session/slices/chat/selectors/utils.test.ts +4 -2
  33. package/src/store/session/slices/chat/selectors/utils.ts +2 -2
  34. package/src/types/chatMessage.ts +9 -0
  35. package/src/types/fetch.ts +18 -14
  36. package/src/types/plugin.ts +2 -2
  37. 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
+ [![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#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
+ [![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#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.55.1",
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": "^1.2.2",
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": "^2",
133
+ "prettier": "^3",
134
134
  "remark": "^14",
135
135
  "remark-cli": "^11",
136
136
  "semantic-release": "^21",
@@ -3,3 +3,5 @@ export const OPENAI_END_POINT = 'X-OPENAI-END_POINT';
3
3
  export const OPENAI_API_KEY_HEADER_KEY = 'X-OPENAI-API-KEY';
4
4
 
5
5
  export const LOBE_CHAT_ACCESS_CODE = 'X-LOBE_CHAT_ACCESS_CODE';
6
+
7
+ export const LOBE_PLUGIN_SETTINGS = 'X-LOBE_PLUGIN_SETTINGS';
@@ -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, useMemo } from 'react';
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 { AgentAction } from '@/store/session/slices/agentConfig';
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 plugin: ItemGroup = useMemo(() => {
47
- let children;
57
+ const plugins = useSessionStore(agentSelectors.currentAgentPlugins);
48
58
 
49
- const loadingItem = {
50
- avatar: (
51
- <Skeleton
52
- active
53
- avatar={{ size: 40 }}
54
- className={styles.avatar}
55
- paragraph={false}
56
- title={false}
57
- />
58
- ),
59
- label: (
60
- <Skeleton
61
- active
62
- avatar={false}
63
- paragraph={{ className: styles.label, style: { marginBottom: 0 } }}
64
- style={{ width: 300 }}
65
- title={false}
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
- children = !data
71
- ? [loadingItem, loadingItem, loadingItem]
72
- : data.plugins.map((item) => ({
73
- avatar: <Avatar avatar={item.meta.avatar} />,
74
- children: (
75
- <Switch
76
- checked={
77
- // 如果在加载中,说明激活了
78
- pluginManifestLoading[item.name] || !config.plugins
79
- ? false
80
- : config.plugins.includes(item.name)
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
- loading={pluginManifestLoading[item.name]}
83
- onChange={(checked) => {
84
- updateConfig(item.name, checked);
85
- if (checked) {
86
- fetchPluginManifest(item.name);
87
- }
88
- }}
89
- />
90
- ),
91
- desc: item.meta?.description,
92
- label: t(`plugins.${item.name}` as any, { ns: 'plugin' }),
93
- minWidth: undefined,
94
- tag: item.name,
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
- return {
98
- children,
99
- icon: ToyBrick,
100
- title: t('settingPlugin.title'),
101
- };
102
- }, [config, data?.plugins, pluginManifestLoading]);
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 <Form items={[plugin]} {...FORM_STYLE} />;
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
- InvalidAccessCode: '密码不正确或为空,请输入正确的访问密码,或者添加自定义 OpenAI API Key',
15
- OpenAIBizError: '请求 OpenAI 服务出错,请根据以下信息排查或重试',
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: {
@@ -12,7 +12,7 @@ export default {
12
12
  plugins: {
13
13
  realtimeWeather: '实时天气预报',
14
14
  searchEngine: '搜索引擎',
15
- undefined: '插件检测中...',
15
+ unknown: '插件检测中...',
16
16
  websiteCrawler: '网页内容提取',
17
17
  },
18
18
  };
@@ -128,6 +128,7 @@ export default {
128
128
  },
129
129
  },
130
130
  settingPlugin: {
131
+ config: '{{id}} 插件配置',
131
132
  title: '插件列表',
132
133
  },
133
134
  settingSystem: {
@@ -1,5 +1,5 @@
1
1
  import { getServerConfig } from '@/config/server';
2
- import { ErrorType } from '@/types/fetch';
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: ErrorType.InvalidAccessCode };
21
+ return { auth: false, error: ChatErrorType.InvalidAccessCode };
22
22
  }
23
23
 
24
24
  return { auth: true };
@@ -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 ErrorType.InvalidAccessCode: {
5
+ case ChatErrorType.InvalidAccessCode: {
6
6
  return 401;
7
7
  }
8
8
 
9
- case ErrorType.OpenAIBizError: {
9
+ case ChatErrorType.OpenAIBizError: {
10
10
  return 577;
11
11
  }
12
12
  }
@@ -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 { ErrorType } from '@/types/fetch';
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(ErrorType.GatewayTimeout, { message: error });
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(ErrorType.OpenAIBizError, { ...error, endpoint });
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.settings.defaultAgent.config?.model]);
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;