@lobehub/chat 0.58.0 → 0.60.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 +59 -0
- package/package.json +1 -1
- package/src/const/url.ts +1 -2
- package/src/features/AgentSetting/AgentPlugin/index.tsx +4 -4
- package/src/locales/default/common.ts +1 -0
- package/src/pages/chat/features/Conversation/ChatList/Error/Plugin/PluginSettings.tsx +7 -5
- package/src/pages/chat/features/Conversation/ChatList/Plugins/CustomRender.tsx +6 -4
- package/src/pages/chat/features/Header/PluginTag.tsx +52 -14
- package/src/store/plugin/helpers.ts +26 -0
- package/src/store/plugin/index.ts +1 -0
- package/src/store/plugin/selectors.ts +30 -4
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,65 @@
|
|
|
2
2
|
|
|
3
3
|
# Changelog
|
|
4
4
|
|
|
5
|
+
## [Version 0.60.0](https://github.com/lobehub/lobe-chat/compare/v0.59.0...v0.60.0)
|
|
6
|
+
|
|
7
|
+
<sup>Released on **2023-08-26**</sup>
|
|
8
|
+
|
|
9
|
+
#### ♻ Code Refactoring
|
|
10
|
+
|
|
11
|
+
- **misc**: Refactor with new market index url.
|
|
12
|
+
|
|
13
|
+
#### ✨ Features
|
|
14
|
+
|
|
15
|
+
- **misc**: 支持插件 manifest 加载失败后重试.
|
|
16
|
+
|
|
17
|
+
<br/>
|
|
18
|
+
|
|
19
|
+
<details>
|
|
20
|
+
<summary><kbd>Improvements and Fixes</kbd></summary>
|
|
21
|
+
|
|
22
|
+
#### Code refactoring
|
|
23
|
+
|
|
24
|
+
- **misc**: Refactor with new market index url ([d2834b7](https://github.com/lobehub/lobe-chat/commit/d2834b7))
|
|
25
|
+
|
|
26
|
+
#### What's improved
|
|
27
|
+
|
|
28
|
+
- **misc**: 支持插件 manifest 加载失败后重试 ([f36378e](https://github.com/lobehub/lobe-chat/commit/f36378e))
|
|
29
|
+
|
|
30
|
+
</details>
|
|
31
|
+
|
|
32
|
+
<div align="right">
|
|
33
|
+
|
|
34
|
+
[](#readme-top)
|
|
35
|
+
|
|
36
|
+
</div>
|
|
37
|
+
|
|
38
|
+
## [Version 0.59.0](https://github.com/lobehub/lobe-chat/compare/v0.58.0...v0.59.0)
|
|
39
|
+
|
|
40
|
+
<sup>Released on **2023-08-26**</sup>
|
|
41
|
+
|
|
42
|
+
#### ✨ Features
|
|
43
|
+
|
|
44
|
+
- **misc**: 支持展示插件插件状态, 支持插件 i18n 模式展示.
|
|
45
|
+
|
|
46
|
+
<br/>
|
|
47
|
+
|
|
48
|
+
<details>
|
|
49
|
+
<summary><kbd>Improvements and Fixes</kbd></summary>
|
|
50
|
+
|
|
51
|
+
#### What's improved
|
|
52
|
+
|
|
53
|
+
- **misc**: 支持展示插件插件状态 ([7e916ac](https://github.com/lobehub/lobe-chat/commit/7e916ac))
|
|
54
|
+
- **misc**: 支持插件 i18n 模式展示 ([8614734](https://github.com/lobehub/lobe-chat/commit/8614734))
|
|
55
|
+
|
|
56
|
+
</details>
|
|
57
|
+
|
|
58
|
+
<div align="right">
|
|
59
|
+
|
|
60
|
+
[](#readme-top)
|
|
61
|
+
|
|
62
|
+
</div>
|
|
63
|
+
|
|
5
64
|
## [Version 0.58.0](https://github.com/lobehub/lobe-chat/compare/v0.57.0...v0.58.0)
|
|
6
65
|
|
|
7
66
|
<sup>Released on **2023-08-26**</sup>
|
package/package.json
CHANGED
package/src/const/url.ts
CHANGED
|
@@ -7,5 +7,4 @@ export const FEEDBACK = pkg.bugs.url;
|
|
|
7
7
|
export const DISCORD = 'https://discord.gg/AYFPHvv2jT';
|
|
8
8
|
|
|
9
9
|
export const PLUGINS_INDEX_URL =
|
|
10
|
-
process.env.PLUGINS_INDEX_URL ??
|
|
11
|
-
'https://registry.npmmirror.com/@lobehub/lobe-chat-plugins/latest/files';
|
|
10
|
+
process.env.PLUGINS_INDEX_URL ?? 'https://chat-plugins-index.lobehub.com';
|
|
@@ -9,7 +9,7 @@ import { useTranslation } from 'react-i18next';
|
|
|
9
9
|
import { FORM_STYLE } from '@/const/layoutTokens';
|
|
10
10
|
import { transformPluginSettings } from '@/features/PluginSettings';
|
|
11
11
|
import PluginSettingRender from '@/features/PluginSettings/PluginSettingRender';
|
|
12
|
-
import { usePluginStore } from '@/store/plugin';
|
|
12
|
+
import { pluginHelpers, usePluginStore } from '@/store/plugin';
|
|
13
13
|
import { useSessionStore } from '@/store/session';
|
|
14
14
|
import { AgentAction, agentSelectors } from '@/store/session/slices/agentConfig';
|
|
15
15
|
import { LobeAgentConfig } from '@/types/session';
|
|
@@ -98,8 +98,8 @@ const AgentPlugin = memo<AgentPluginProps>(({ config, updateConfig }) => {
|
|
|
98
98
|
}}
|
|
99
99
|
/>
|
|
100
100
|
),
|
|
101
|
-
desc: meta
|
|
102
|
-
label: meta
|
|
101
|
+
desc: pluginHelpers.getPluginDesc(meta),
|
|
102
|
+
label: pluginHelpers.getPluginTitle(meta),
|
|
103
103
|
minWidth: undefined,
|
|
104
104
|
tag: identifier,
|
|
105
105
|
}));
|
|
@@ -131,7 +131,7 @@ const AgentPlugin = memo<AgentPluginProps>(({ config, updateConfig }) => {
|
|
|
131
131
|
desc: item.desc && <Markdown className={styles.md}>{item.desc}</Markdown>,
|
|
132
132
|
})),
|
|
133
133
|
icon: ToyBrick,
|
|
134
|
-
title: t('settingPlugin.config', { id: item.meta
|
|
134
|
+
title: t('settingPlugin.config', { id: pluginHelpers.getPluginTitle(item.meta) }),
|
|
135
135
|
};
|
|
136
136
|
})
|
|
137
137
|
.filter(Boolean) as unknown as ItemGroup[]);
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import { Avatar } from '@lobehub/ui';
|
|
2
2
|
import { Button, Divider } from 'antd';
|
|
3
3
|
import { useTheme } from 'antd-style';
|
|
4
|
+
import isEqual from 'fast-deep-equal';
|
|
4
5
|
import { memo } from 'react';
|
|
5
6
|
import { useTranslation } from 'react-i18next';
|
|
6
7
|
import { Center, Flexbox } from 'react-layout-kit';
|
|
7
8
|
|
|
8
9
|
import PluginSettingsConfig from '@/features/PluginSettings';
|
|
9
|
-
import { pluginSelectors, usePluginStore } from '@/store/plugin';
|
|
10
|
+
import { pluginHelpers, pluginSelectors, usePluginStore } from '@/store/plugin';
|
|
10
11
|
import { useSessionStore } from '@/store/session';
|
|
11
12
|
|
|
12
13
|
import { ErrorActionContainer, useStyles } from '../style';
|
|
@@ -22,20 +23,21 @@ const PluginSettings = memo<PluginSettingsProps>(({ id, pluginIdentifier }) => {
|
|
|
22
23
|
const { t } = useTranslation('error');
|
|
23
24
|
const theme = useTheme();
|
|
24
25
|
const [resend, deleteMessage] = useSessionStore((s) => [s.resendMessage, s.deleteMessage]);
|
|
25
|
-
|
|
26
|
-
const
|
|
26
|
+
|
|
27
|
+
const plugin = usePluginStore(pluginSelectors.getPluginMetaById(pluginIdentifier), isEqual);
|
|
28
|
+
const manifest = usePluginStore(pluginSelectors.getPluginManifestById(pluginIdentifier), isEqual);
|
|
27
29
|
|
|
28
30
|
return (
|
|
29
31
|
<ErrorActionContainer>
|
|
30
32
|
<Center gap={16} style={{ maxWidth: 400 }}>
|
|
31
33
|
<Avatar
|
|
32
|
-
avatar={plugin?.meta
|
|
34
|
+
avatar={pluginHelpers.getPluginAvatar(plugin?.meta) || '⚙️'}
|
|
33
35
|
background={theme.colorFillContent}
|
|
34
36
|
gap={12}
|
|
35
37
|
size={80}
|
|
36
38
|
/>
|
|
37
39
|
<Flexbox style={{ fontSize: 20 }}>
|
|
38
|
-
{t('pluginSettings.title', { name: plugin?.meta
|
|
40
|
+
{t('pluginSettings.title', { name: pluginHelpers.getPluginTitle(plugin?.meta) })}
|
|
39
41
|
</Flexbox>
|
|
40
42
|
<Flexbox className={styles.desc}>{t('pluginSettings.desc')}</Flexbox>
|
|
41
43
|
<Divider style={{ margin: '0 16px' }} />
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { PluginRender, PluginRenderProps } from '@lobehub/chat-plugin-sdk';
|
|
2
2
|
import { Skeleton } from 'antd';
|
|
3
|
-
import { memo, useState } from 'react';
|
|
3
|
+
import { memo, useEffect, useState } from 'react';
|
|
4
4
|
|
|
5
5
|
import { system } from './dynamticLoader';
|
|
6
6
|
|
|
@@ -10,7 +10,7 @@ interface CustomRenderProps extends PluginRenderProps {
|
|
|
10
10
|
const CustomRender = memo<CustomRenderProps>(({ url, ...props }) => {
|
|
11
11
|
const [component, setComp] = useState<PluginRender | null>(null);
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
useEffect(() => {
|
|
14
14
|
system
|
|
15
15
|
.import(url)
|
|
16
16
|
.then((module1) => {
|
|
@@ -21,12 +21,14 @@ const CustomRender = memo<CustomRenderProps>(({ url, ...props }) => {
|
|
|
21
21
|
setComp(null);
|
|
22
22
|
console.error(error);
|
|
23
23
|
});
|
|
24
|
+
}, [url]);
|
|
24
25
|
|
|
26
|
+
if (!component) {
|
|
25
27
|
return <Skeleton active style={{ width: 300 }} />;
|
|
26
28
|
}
|
|
27
29
|
|
|
28
|
-
const
|
|
30
|
+
const Render = component;
|
|
29
31
|
|
|
30
|
-
return <
|
|
32
|
+
return <Render {...props} />;
|
|
31
33
|
});
|
|
32
34
|
export default CustomRender;
|
|
@@ -1,33 +1,71 @@
|
|
|
1
|
-
import { Avatar, Icon, Tag } from '@lobehub/ui';
|
|
1
|
+
import { ActionIcon, Avatar, Icon, Tag } from '@lobehub/ui';
|
|
2
2
|
import type { MenuProps } from 'antd';
|
|
3
|
-
import { Dropdown } from 'antd';
|
|
4
|
-
import
|
|
5
|
-
import {
|
|
3
|
+
import { Badge, Dropdown } from 'antd';
|
|
4
|
+
import isEqual from 'fast-deep-equal';
|
|
5
|
+
import { LucideRotateCw, LucideToyBrick } from 'lucide-react';
|
|
6
|
+
import { memo, useMemo } from 'react';
|
|
6
7
|
import { useTranslation } from 'react-i18next';
|
|
8
|
+
import { Flexbox } from 'react-layout-kit';
|
|
7
9
|
|
|
8
|
-
import { usePluginStore } from '@/store/plugin';
|
|
10
|
+
import { pluginHelpers, pluginSelectors, usePluginStore } from '@/store/plugin';
|
|
11
|
+
|
|
12
|
+
const PluginStatus = memo<{ id: string; title?: string }>(({ title, id }) => {
|
|
13
|
+
const { t } = useTranslation('common');
|
|
14
|
+
const [status, fetchPluginManifest] = usePluginStore((s) => [
|
|
15
|
+
pluginSelectors.getPluginManifestLoadingStatus(id)(s),
|
|
16
|
+
s.fetchPluginManifest,
|
|
17
|
+
]);
|
|
18
|
+
|
|
19
|
+
const renderStatus = useMemo(() => {
|
|
20
|
+
switch (status) {
|
|
21
|
+
case 'loading': {
|
|
22
|
+
return <Badge color={'blue'} status={'processing'} />;
|
|
23
|
+
}
|
|
24
|
+
case 'error': {
|
|
25
|
+
return (
|
|
26
|
+
<ActionIcon
|
|
27
|
+
icon={LucideRotateCw}
|
|
28
|
+
onClick={() => {
|
|
29
|
+
fetchPluginManifest(id);
|
|
30
|
+
}}
|
|
31
|
+
size={'small'}
|
|
32
|
+
title={t('retry')}
|
|
33
|
+
/>
|
|
34
|
+
);
|
|
35
|
+
}
|
|
36
|
+
case 'success': {
|
|
37
|
+
return <Badge status={status} />;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}, [status]);
|
|
41
|
+
|
|
42
|
+
return (
|
|
43
|
+
<Flexbox gap={12} horizontal justify={'space-between'}>
|
|
44
|
+
{title} {renderStatus}
|
|
45
|
+
</Flexbox>
|
|
46
|
+
);
|
|
47
|
+
});
|
|
9
48
|
|
|
10
49
|
export interface PluginTagProps {
|
|
11
50
|
plugins: string[];
|
|
12
51
|
}
|
|
13
52
|
|
|
14
53
|
const PluginTag = memo<PluginTagProps>(({ plugins }) => {
|
|
15
|
-
const
|
|
16
|
-
|
|
17
|
-
const list = usePluginStore((s) => s.pluginList);
|
|
54
|
+
const list = usePluginStore(pluginSelectors.displayPluginList);
|
|
55
|
+
const displayPlugin = usePluginStore(pluginSelectors.getPluginMetaById(plugins[0]), isEqual);
|
|
18
56
|
|
|
19
57
|
if (plugins.length === 0) return null;
|
|
20
58
|
|
|
21
59
|
const items: MenuProps['items'] = plugins.map((id) => {
|
|
22
|
-
const item = list
|
|
60
|
+
const item = list.find((i) => i.identifier === id);
|
|
61
|
+
|
|
23
62
|
return {
|
|
24
|
-
icon:
|
|
25
|
-
<Avatar avatar={item?.meta.avatar} size={24} style={{ marginLeft: -6, marginRight: 2 }} />
|
|
26
|
-
),
|
|
63
|
+
icon: <Avatar avatar={item?.avatar} size={24} style={{ marginLeft: -6, marginRight: 2 }} />,
|
|
27
64
|
key: id,
|
|
28
|
-
label:
|
|
65
|
+
label: <PluginStatus id={id} title={item?.title} />,
|
|
29
66
|
};
|
|
30
67
|
});
|
|
68
|
+
|
|
31
69
|
const count = plugins.length;
|
|
32
70
|
|
|
33
71
|
return (
|
|
@@ -35,7 +73,7 @@ const PluginTag = memo<PluginTagProps>(({ plugins }) => {
|
|
|
35
73
|
<div>
|
|
36
74
|
<Tag>
|
|
37
75
|
{<Icon icon={LucideToyBrick} />}
|
|
38
|
-
{
|
|
76
|
+
{pluginHelpers.getPluginTitle(displayPlugin?.meta)}
|
|
39
77
|
{count > 1 && <div>({plugins.length - 1}+)</div>}
|
|
40
78
|
</Tag>
|
|
41
79
|
</div>
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { LobeChatPluginMeta } from '@lobehub/chat-plugin-sdk';
|
|
2
|
+
import i18n from 'i18next';
|
|
3
|
+
|
|
4
|
+
const getI18nValue = (value: string | Record<string, string> | undefined) => {
|
|
5
|
+
if (!value) return;
|
|
6
|
+
|
|
7
|
+
if (typeof value === 'string') return value;
|
|
8
|
+
|
|
9
|
+
if (value[i18n.language]) return value[i18n.language];
|
|
10
|
+
|
|
11
|
+
return Object.values(value)[0];
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
const getPluginFormList = (pluginList: LobeChatPluginMeta[], id: string) =>
|
|
15
|
+
pluginList?.find((p) => p.identifier === id);
|
|
16
|
+
|
|
17
|
+
const getPluginTitle = (meta?: LobeChatPluginMeta['meta']) => getI18nValue(meta?.title);
|
|
18
|
+
const getPluginDesc = (meta?: LobeChatPluginMeta['meta']) => getI18nValue(meta?.description);
|
|
19
|
+
const getPluginAvatar = (meta?: LobeChatPluginMeta['meta']) => meta?.avatar;
|
|
20
|
+
|
|
21
|
+
export const pluginHelpers = {
|
|
22
|
+
getPluginAvatar,
|
|
23
|
+
getPluginDesc,
|
|
24
|
+
getPluginFormList,
|
|
25
|
+
getPluginTitle,
|
|
26
|
+
};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { PLUGIN_SCHEMA_SEPARATOR } from '@/const/plugin';
|
|
2
|
+
import { pluginHelpers } from '@/store/plugin/helpers';
|
|
2
3
|
|
|
3
4
|
import { PluginStoreState } from './initialState';
|
|
4
5
|
|
|
@@ -23,13 +24,38 @@ const enabledSchema =
|
|
|
23
24
|
};
|
|
24
25
|
|
|
25
26
|
const getPluginMetaById = (id: string) => (s: PluginStoreState) =>
|
|
26
|
-
s.pluginList
|
|
27
|
+
pluginHelpers.getPluginFormList(s.pluginList, id);
|
|
27
28
|
|
|
28
|
-
const
|
|
29
|
-
|
|
29
|
+
const getPluginManifestById = (id: string) => (s: PluginStoreState) => s.pluginManifestMap[id];
|
|
30
|
+
const getPluginSettingsById = (id: string) => (s: PluginStoreState) => s.pluginsSettings[id];
|
|
31
|
+
|
|
32
|
+
// 获取插件 manifest 加载状态
|
|
33
|
+
const getPluginManifestLoadingStatus = (id: string) => (s: PluginStoreState) => {
|
|
34
|
+
const manifest = getPluginManifestById(id);
|
|
35
|
+
|
|
36
|
+
if (s.pluginManifestLoading[id]) return 'loading';
|
|
37
|
+
|
|
38
|
+
if (!manifest) return 'error';
|
|
39
|
+
|
|
40
|
+
if (!!manifest) return 'success';
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
const displayPluginList = (s: PluginStoreState) =>
|
|
44
|
+
s.pluginList.map((p) => ({
|
|
45
|
+
author: p.author,
|
|
46
|
+
avatar: p.meta?.avatar,
|
|
47
|
+
createAt: p.createAt,
|
|
48
|
+
desc: pluginHelpers.getPluginDesc(p.meta),
|
|
49
|
+
homepage: p.homepage,
|
|
50
|
+
identifier: p.identifier,
|
|
51
|
+
title: pluginHelpers.getPluginTitle(p.meta),
|
|
52
|
+
}));
|
|
30
53
|
|
|
31
54
|
export const pluginSelectors = {
|
|
55
|
+
displayPluginList,
|
|
32
56
|
enabledSchema,
|
|
33
|
-
|
|
57
|
+
getPluginManifestById,
|
|
58
|
+
getPluginManifestLoadingStatus,
|
|
34
59
|
getPluginMetaById,
|
|
60
|
+
getPluginSettingsById,
|
|
35
61
|
};
|