@lobehub/chat 0.111.5 → 0.112.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/.env.example +1 -1
- package/.i18nrc.js +1 -0
- package/CHANGELOG.md +84 -0
- package/README.md +2 -2
- package/README.zh-CN.md +2 -2
- package/docs/Deployment/Environment-Variable.md +1 -1
- package/docs/Deployment/Environment-Variable.zh-CN.md +1 -1
- package/docs/Deployment/Upstream-Sync.md +1 -1
- package/docs/Deployment/Upstream-Sync.zh-CN.md +1 -1
- package/docs/Home.md +26 -26
- package/docs/Plugins/Plugin-Development.md +1 -1
- package/docs/Plugins/Plugin-Development.zh-CN.md +1 -1
- package/docs/_Sidebar.md +20 -20
- package/locales/en_US/chat.json +12 -12
- package/locales/en_US/common.json +13 -13
- package/locales/en_US/error.json +16 -14
- package/locales/en_US/market.json +2 -2
- package/locales/en_US/migration.json +4 -4
- package/locales/en_US/plugin.json +75 -38
- package/locales/en_US/setting.json +7 -7
- package/locales/fr_FR/chat.json +11 -11
- package/locales/fr_FR/common.json +14 -14
- package/locales/fr_FR/error.json +12 -10
- package/locales/fr_FR/plugin.json +42 -5
- package/locales/fr_FR/setting.json +12 -12
- package/locales/fr_FR/welcome.json +3 -3
- package/locales/ja_JP/chat.json +1 -1
- package/locales/ja_JP/common.json +3 -3
- package/locales/ja_JP/error.json +16 -14
- package/locales/ja_JP/migration.json +4 -4
- package/locales/ja_JP/plugin.json +70 -33
- package/locales/ja_JP/setting.json +1 -1
- package/locales/ko_KR/chat.json +1 -1
- package/locales/ko_KR/common.json +3 -3
- package/locales/ko_KR/error.json +16 -14
- package/locales/ko_KR/migration.json +4 -4
- package/locales/ko_KR/plugin.json +71 -34
- package/locales/ko_KR/setting.json +1 -1
- package/locales/ru_RU/chat.json +1 -1
- package/locales/ru_RU/common.json +3 -3
- package/locales/ru_RU/error.json +16 -14
- package/locales/ru_RU/market.json +2 -2
- package/locales/ru_RU/migration.json +4 -4
- package/locales/ru_RU/plugin.json +71 -34
- package/locales/ru_RU/setting.json +1 -1
- package/locales/zh_CN/chat.json +1 -1
- package/locales/zh_CN/common.json +1 -1
- package/locales/zh_CN/error.json +2 -0
- package/locales/zh_CN/plugin.json +42 -5
- package/locales/zh_CN/setting.json +1 -1
- package/locales/zh_TW/chat.json +1 -1
- package/locales/zh_TW/common.json +3 -3
- package/locales/zh_TW/error.json +16 -14
- package/locales/zh_TW/market.json +2 -2
- package/locales/zh_TW/migration.json +4 -4
- package/locales/zh_TW/plugin.json +98 -61
- package/locales/zh_TW/setting.json +1 -1
- package/package.json +3 -1
- package/scripts/docsWorkflow/index.ts +5 -2
- package/scripts/docsWorkflow/toc.ts +2 -2
- package/scripts/i18nWorkflow/genDiff.ts +7 -8
- package/scripts/i18nWorkflow/utils.ts +0 -14
- package/scripts/readmeWorkflow/syncPluginIndex.ts +9 -11
- package/src/app/api/plugins/route.ts +2 -4
- package/src/app/api/proxy/route.ts +10 -0
- package/src/app/chat/features/ChatInput/ActionBar/Tools/ToolItem.tsx +3 -8
- package/src/app/chat/features/ChatInput/ActionBar/Tools/index.tsx +3 -3
- package/src/app/chat/features/Conversation/ChatList/Error/index.tsx +6 -0
- package/src/app/chat/features/Conversation/ChatList/Messages/Function.tsx +1 -1
- package/src/app/chat/features/Conversation/ChatList/Plugins/Inspector/Settings.tsx +7 -5
- package/src/app/chat/features/Conversation/ChatList/Plugins/Inspector/index.tsx +2 -2
- package/src/app/chat/features/Conversation/ChatList/Plugins/Render/DefaultType/index.tsx +6 -4
- package/src/app/chat/features/Conversation/ChatList/Plugins/Render/index.tsx +2 -2
- package/src/app/chat/features/Migration/ExportConfigButton.tsx +1 -1
- package/src/app/market/features/AgentDetailContent/AgentInfo/index.tsx +1 -0
- package/src/app/market/features/AgentDetailContent/AgentInfo/style.ts +1 -9
- package/src/app/settings/common/Common.tsx +5 -7
- package/src/app/settings/features/UpgradeAlert.tsx +2 -2
- package/src/components/FileList/FileItem.tsx +4 -2
- package/src/components/HotKeys/index.tsx +5 -4
- package/src/const/plugin.ts +1 -0
- package/src/const/url.ts +1 -0
- package/src/const/version.ts +0 -3
- package/src/features/AgentSetting/AgentPlugin/AddPluginButton.tsx +2 -2
- package/src/features/AgentSetting/AgentPlugin/LocalPluginItem.tsx +19 -53
- package/src/features/AgentSetting/AgentPlugin/index.tsx +5 -11
- package/src/features/AgentSetting/store/initialState.ts +1 -1
- package/src/features/PluginDetailModal/APIs.tsx +44 -0
- package/src/features/PluginDetailModal/Meta.tsx +59 -0
- package/src/features/PluginDetailModal/index.tsx +79 -0
- package/src/features/PluginDevModal/PluginPreview.tsx +8 -10
- package/src/features/PluginDevModal/UrlManifestForm.tsx +131 -0
- package/src/features/PluginDevModal/index.tsx +31 -32
- package/src/features/PluginSettings/index.tsx +1 -1
- package/src/features/PluginStore/AddPluginButton.tsx +47 -0
- package/src/features/PluginStore/InstalledPluginList.tsx +54 -0
- package/src/features/PluginStore/OnlineList.tsx +95 -0
- package/src/features/PluginStore/PluginItem/Action.tsx +118 -0
- package/src/features/PluginStore/PluginItem/EditCustomPlugin.tsx +50 -0
- package/src/features/PluginStore/PluginItem/PluginTag.tsx +58 -0
- package/src/features/PluginStore/PluginItem/index.tsx +73 -0
- package/src/features/PluginStore/index.tsx +20 -92
- package/src/hooks/usePlatform.ts +15 -0
- package/src/locales/default/chat.ts +1 -1
- package/src/locales/default/common.ts +1 -1
- package/src/locales/default/error.ts +2 -0
- package/src/locales/default/plugin.ts +41 -4
- package/src/locales/default/setting.ts +1 -1
- package/src/services/__tests__/__snapshots__/plugin.test.ts.snap +154 -0
- package/src/services/__tests__/chat.test.ts +1 -1
- package/src/services/__tests__/global.test.ts +57 -0
- package/src/services/__tests__/openai/OpenAPI_V3.json +245 -0
- package/src/services/__tests__/openai/plugin.json +22 -0
- package/src/services/__tests__/plugin.test.ts +90 -1
- package/src/services/__tests__/share.test.ts +86 -0
- package/src/services/_url.ts +2 -0
- package/src/services/global.ts +15 -0
- package/src/services/plugin.ts +99 -15
- package/src/services/share.ts +34 -0
- package/src/store/chat/actions/enhance.test.ts +15 -15
- package/src/store/chat/actions/message.test.ts +3 -2
- package/src/store/chat/actions/plugin.test.ts +281 -0
- package/src/store/chat/actions/plugin.ts +22 -3
- package/src/store/chat/actions/share.ts +2 -2
- package/src/store/chat/actions/topic.test.ts +12 -4
- package/src/store/global/slices/common.ts +2 -2
- package/src/store/session/selectors.ts +1 -1
- package/src/store/session/slices/agent/selectors.ts +1 -1
- package/src/store/tool/helpers.ts +8 -1
- package/src/store/tool/slices/customPlugin/action.ts +4 -1
- package/src/store/tool/slices/plugin/selectors.test.ts +22 -3
- package/src/store/tool/slices/plugin/selectors.ts +24 -5
- package/src/store/tool/slices/store/selectors.test.ts +18 -1
- package/src/store/tool/slices/store/selectors.ts +14 -3
- package/src/styles/antdOverride.ts +7 -0
- package/src/types/openai/chat.ts +0 -1
- package/src/types/openai/plugin.ts +57 -0
- package/src/types/tool/index.ts +1 -2
- package/src/types/tool/plugin.ts +13 -1
- package/src/types/tool/tool.ts +1 -0
- package/src/types/translate.ts +0 -1
- package/src/utils/platform.ts +8 -5
- package/src/features/PluginDevModal/UrlModeForm.tsx +0 -98
- package/src/features/PluginSettingsModal/index.tsx +0 -59
- package/src/features/PluginStore/PluginItem.tsx +0 -82
- package/src/features/PluginStore/PluginSettings.tsx +0 -40
- package/src/services/latestVersion.ts +0 -11
- package/src/services/shareGPT.ts +0 -28
|
@@ -27,7 +27,24 @@ describe('pluginStoreSelectors', () => {
|
|
|
27
27
|
describe('onlinePluginStore', () => {
|
|
28
28
|
it('should return the online plugin list', () => {
|
|
29
29
|
const result = pluginStoreSelectors.onlinePluginStore(mockState);
|
|
30
|
-
expect(result).toEqual(
|
|
30
|
+
expect(result).toEqual([
|
|
31
|
+
{
|
|
32
|
+
identifier: 'plugin-1',
|
|
33
|
+
author: 'Author 1',
|
|
34
|
+
createdAt: '2021-01-01',
|
|
35
|
+
meta: { avatar: 'avatar-url-1', title: 'Plugin 1' },
|
|
36
|
+
homepage: 'http://homepage-1.com',
|
|
37
|
+
type: 'plugin',
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
identifier: 'plugin-2',
|
|
41
|
+
author: 'Author 2',
|
|
42
|
+
createdAt: '2022-02-02',
|
|
43
|
+
meta: { avatar: 'avatar-url-2', title: 'Plugin 2' },
|
|
44
|
+
homepage: 'http://homepage-2.com',
|
|
45
|
+
type: 'plugin',
|
|
46
|
+
},
|
|
47
|
+
]);
|
|
31
48
|
});
|
|
32
49
|
});
|
|
33
50
|
});
|
|
@@ -1,11 +1,22 @@
|
|
|
1
|
+
import { InstallPluginMeta } from '@/types/tool/plugin';
|
|
2
|
+
|
|
1
3
|
import type { ToolStoreState } from '../../initialState';
|
|
2
4
|
|
|
3
5
|
const onlinePluginStore = (s: ToolStoreState) => {
|
|
4
|
-
if (s.listType === 'all') return s.pluginStoreList;
|
|
5
|
-
|
|
6
6
|
const installedPluginIds = new Set(s.installedPlugins.map((i) => i.identifier));
|
|
7
|
+
const list =
|
|
8
|
+
s.listType === 'all'
|
|
9
|
+
? s.pluginStoreList
|
|
10
|
+
: s.pluginStoreList.filter((p) => installedPluginIds.has(p.identifier));
|
|
7
11
|
|
|
8
|
-
return
|
|
12
|
+
return list.map<InstallPluginMeta>((p) => ({
|
|
13
|
+
author: p.author,
|
|
14
|
+
createdAt: p.createdAt,
|
|
15
|
+
homepage: p.homepage,
|
|
16
|
+
identifier: p.identifier,
|
|
17
|
+
meta: p.meta,
|
|
18
|
+
type: 'plugin',
|
|
19
|
+
}));
|
|
9
20
|
};
|
|
10
21
|
|
|
11
22
|
const isPluginInstallLoading = (id: string) => (s: ToolStoreState) => s.pluginInstallLoading[id];
|
|
@@ -4,4 +4,11 @@ export default ({ token }: { prefixCls: string; token: Theme }) => css`
|
|
|
4
4
|
.${token.prefixCls}-popover {
|
|
5
5
|
z-index: 1100;
|
|
6
6
|
}
|
|
7
|
+
.${token.prefixCls}-dropdown {
|
|
8
|
+
> ul {
|
|
9
|
+
border: 1px solid ${token.colorBorderSecondary};
|
|
10
|
+
border-radius: ${token.borderRadius}px !important;
|
|
11
|
+
box-shadow: ${token.boxShadowSecondary};
|
|
12
|
+
}
|
|
13
|
+
}
|
|
7
14
|
`;
|
package/src/types/openai/chat.ts
CHANGED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
type HttpAuthorizationType = 'bearer' | 'basic';
|
|
2
|
+
|
|
3
|
+
interface BaseManifestAuth {
|
|
4
|
+
instructions: string;
|
|
5
|
+
type: string;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
interface ManifestNoAuth extends BaseManifestAuth {
|
|
9
|
+
type: 'none';
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
interface ManifestServiceHttpAuth extends BaseManifestAuth {
|
|
13
|
+
authorization_type: HttpAuthorizationType;
|
|
14
|
+
type: 'service_http';
|
|
15
|
+
verification_tokens: {
|
|
16
|
+
[service: string]: string;
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
interface ManifestUserHttpAuth extends BaseManifestAuth {
|
|
21
|
+
authorization_type: HttpAuthorizationType;
|
|
22
|
+
type: 'user_http';
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
interface ManifestOAuthAuth extends BaseManifestAuth {
|
|
26
|
+
authorization_content_type: string;
|
|
27
|
+
authorization_url: string;
|
|
28
|
+
client_url: string;
|
|
29
|
+
scope: string;
|
|
30
|
+
type: 'oauth';
|
|
31
|
+
verification_tokens: {
|
|
32
|
+
[service: string]: string;
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
type ManifestAuth =
|
|
37
|
+
| ManifestNoAuth
|
|
38
|
+
| ManifestServiceHttpAuth
|
|
39
|
+
| ManifestUserHttpAuth
|
|
40
|
+
| ManifestOAuthAuth;
|
|
41
|
+
|
|
42
|
+
export interface OpenAIPluginManifest {
|
|
43
|
+
api: {
|
|
44
|
+
type: string;
|
|
45
|
+
url: string;
|
|
46
|
+
};
|
|
47
|
+
auth: ManifestAuth;
|
|
48
|
+
contact_email: string;
|
|
49
|
+
description_for_human: string;
|
|
50
|
+
description_for_model: string;
|
|
51
|
+
legal_info_url: string;
|
|
52
|
+
logo_url: string;
|
|
53
|
+
name_for_human: string;
|
|
54
|
+
name_for_model: string;
|
|
55
|
+
schema_version: string;
|
|
56
|
+
// 其他可能的字段...
|
|
57
|
+
}
|
package/src/types/tool/index.ts
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import { LobeChatPluginManifest } from '@lobehub/chat-plugin-sdk';
|
|
2
2
|
|
|
3
3
|
import { CustomPluginParams } from './plugin';
|
|
4
|
-
|
|
5
|
-
export type LobeToolType = 'builtin' | 'customPlugin' | 'plugin';
|
|
4
|
+
import { LobeToolType } from './tool';
|
|
6
5
|
|
|
7
6
|
export interface LobeTool {
|
|
8
7
|
customParams?: CustomPluginParams;
|
package/src/types/tool/plugin.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import { LobeChatPluginManifest } from '@lobehub/chat-plugin-sdk';
|
|
1
|
+
import { LobeChatPluginManifest, Meta } from '@lobehub/chat-plugin-sdk';
|
|
2
|
+
|
|
3
|
+
import { LobeToolType } from './tool';
|
|
2
4
|
|
|
3
5
|
export type PluginManifestMap = Record<string, LobeChatPluginManifest>;
|
|
4
6
|
|
|
@@ -7,6 +9,7 @@ export interface CustomPluginParams {
|
|
|
7
9
|
enableSettings?: boolean;
|
|
8
10
|
manifestMode?: 'local' | 'url';
|
|
9
11
|
manifestUrl?: string;
|
|
12
|
+
useProxy?: boolean;
|
|
10
13
|
}
|
|
11
14
|
|
|
12
15
|
export interface LobeToolCustomPlugin {
|
|
@@ -17,6 +20,15 @@ export interface LobeToolCustomPlugin {
|
|
|
17
20
|
type: 'customPlugin';
|
|
18
21
|
}
|
|
19
22
|
|
|
23
|
+
export interface InstallPluginMeta {
|
|
24
|
+
author?: string;
|
|
25
|
+
createdAt?: string;
|
|
26
|
+
homepage?: string;
|
|
27
|
+
identifier: string;
|
|
28
|
+
meta?: Meta;
|
|
29
|
+
type: LobeToolType;
|
|
30
|
+
}
|
|
31
|
+
|
|
20
32
|
export interface PluginInstallError {
|
|
21
33
|
cause?: string;
|
|
22
34
|
message: 'noManifest' | 'fetchError' | 'manifestInvalid' | 'urlError';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export type LobeToolType = 'builtin' | 'customPlugin' | 'plugin';
|
package/src/types/translate.ts
CHANGED
package/src/utils/platform.ts
CHANGED
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
import UAParser from 'ua-parser-js';
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
const getPaser = () => {
|
|
4
4
|
let ua = navigator.userAgent;
|
|
5
|
-
return new UAParser(ua)
|
|
5
|
+
return new UAParser(ua);
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
export const getPlatform = () => {
|
|
9
|
+
return getPaser().getOS().name;
|
|
6
10
|
};
|
|
7
11
|
|
|
8
|
-
export const
|
|
9
|
-
|
|
10
|
-
return platform && ['Mac OS', 'iOS'].includes(platform);
|
|
12
|
+
export const getBrowser = () => {
|
|
13
|
+
return getPaser().getResult().browser.name;
|
|
11
14
|
};
|
|
@@ -1,98 +0,0 @@
|
|
|
1
|
-
import { LobeChatPluginManifest } from '@lobehub/chat-plugin-sdk';
|
|
2
|
-
import { ActionIcon, FormItem, Input } from '@lobehub/ui';
|
|
3
|
-
import { Form, FormInstance } from 'antd';
|
|
4
|
-
import { FileCode, RotateCwIcon } from 'lucide-react';
|
|
5
|
-
import { memo, useState } from 'react';
|
|
6
|
-
import { useTranslation } from 'react-i18next';
|
|
7
|
-
import { Flexbox } from 'react-layout-kit';
|
|
8
|
-
|
|
9
|
-
import ManifestPreviewer from '@/components/ManifestPreviewer';
|
|
10
|
-
import { pluginService } from '@/services/plugin';
|
|
11
|
-
import { useToolStore } from '@/store/tool';
|
|
12
|
-
import { pluginSelectors } from '@/store/tool/selectors';
|
|
13
|
-
import { PluginInstallError } from '@/types/tool/plugin';
|
|
14
|
-
|
|
15
|
-
const UrlModeForm = memo<{ form: FormInstance; isEditMode: boolean }>(({ form, isEditMode }) => {
|
|
16
|
-
const { t } = useTranslation('plugin');
|
|
17
|
-
|
|
18
|
-
const [manifest, setManifest] = useState<LobeChatPluginManifest>();
|
|
19
|
-
|
|
20
|
-
const urlKey = ['customParams', 'manifestUrl'];
|
|
21
|
-
const pluginIds = useToolStore(pluginSelectors.storeAndInstallPluginsIdList);
|
|
22
|
-
|
|
23
|
-
return (
|
|
24
|
-
<Form form={form} layout={'vertical'}>
|
|
25
|
-
<FormItem
|
|
26
|
-
extra={
|
|
27
|
-
<Flexbox horizontal justify={'space-between'} style={{ marginTop: 8 }}>
|
|
28
|
-
{t('dev.meta.manifest.desc')}
|
|
29
|
-
{manifest && (
|
|
30
|
-
<ManifestPreviewer manifest={manifest}>
|
|
31
|
-
<ActionIcon icon={FileCode} size={'small'} title={t('dev.meta.manifest.preview')} />
|
|
32
|
-
</ManifestPreviewer>
|
|
33
|
-
)}
|
|
34
|
-
</Flexbox>
|
|
35
|
-
}
|
|
36
|
-
hasFeedback
|
|
37
|
-
label={t('dev.meta.manifest.label')}
|
|
38
|
-
name={urlKey}
|
|
39
|
-
required
|
|
40
|
-
rules={[
|
|
41
|
-
{ required: true },
|
|
42
|
-
{
|
|
43
|
-
message: t('error.urlError'),
|
|
44
|
-
pattern: /^https?:\/\/.*/,
|
|
45
|
-
},
|
|
46
|
-
{
|
|
47
|
-
validator: async (_, value) => {
|
|
48
|
-
if (!value) return true;
|
|
49
|
-
|
|
50
|
-
try {
|
|
51
|
-
const data = await pluginService.getPluginManifest(value);
|
|
52
|
-
setManifest(data);
|
|
53
|
-
|
|
54
|
-
form.setFieldsValue({ identifier: data.identifier, manifest: data });
|
|
55
|
-
} catch (error) {
|
|
56
|
-
const err = error as PluginInstallError;
|
|
57
|
-
throw t(`error.${err.message}`, { error: err.cause! });
|
|
58
|
-
}
|
|
59
|
-
},
|
|
60
|
-
},
|
|
61
|
-
// 编辑模式下,不进行重复校验
|
|
62
|
-
isEditMode
|
|
63
|
-
? {}
|
|
64
|
-
: {
|
|
65
|
-
message: t('dev.meta.identifier.errorDuplicate'),
|
|
66
|
-
validator: async () => {
|
|
67
|
-
const id = form.getFieldValue('identifier');
|
|
68
|
-
if (!id) return true;
|
|
69
|
-
|
|
70
|
-
if (pluginIds.includes(id)) {
|
|
71
|
-
throw new Error('Duplicate');
|
|
72
|
-
}
|
|
73
|
-
},
|
|
74
|
-
},
|
|
75
|
-
]}
|
|
76
|
-
>
|
|
77
|
-
<Input
|
|
78
|
-
placeholder={'http://localhost:3400/manifest-dev.json'}
|
|
79
|
-
suffix={
|
|
80
|
-
<ActionIcon
|
|
81
|
-
icon={RotateCwIcon}
|
|
82
|
-
onClick={(e) => {
|
|
83
|
-
e.stopPropagation();
|
|
84
|
-
form.validateFields([urlKey, 'identifier']);
|
|
85
|
-
}}
|
|
86
|
-
size={'small'}
|
|
87
|
-
title={t('dev.meta.manifest.refresh')}
|
|
88
|
-
/>
|
|
89
|
-
}
|
|
90
|
-
/>
|
|
91
|
-
</FormItem>
|
|
92
|
-
<FormItem name={'identifier'} noStyle />
|
|
93
|
-
<FormItem name={'manifest'} noStyle />
|
|
94
|
-
</Form>
|
|
95
|
-
);
|
|
96
|
-
});
|
|
97
|
-
|
|
98
|
-
export default UrlModeForm;
|
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
import { Avatar, Modal } from '@lobehub/ui';
|
|
2
|
-
import { Divider, Typography } from 'antd';
|
|
3
|
-
import { useTheme } from 'antd-style';
|
|
4
|
-
import isEqual from 'fast-deep-equal';
|
|
5
|
-
import { memo } from 'react';
|
|
6
|
-
import { useTranslation } from 'react-i18next';
|
|
7
|
-
import { Center, Flexbox } from 'react-layout-kit';
|
|
8
|
-
|
|
9
|
-
import MobilePadding from '@/components/MobilePadding';
|
|
10
|
-
import PluginSettingsConfig from '@/features/PluginSettings';
|
|
11
|
-
import { pluginHelpers, useToolStore } from '@/store/tool';
|
|
12
|
-
import { pluginSelectors } from '@/store/tool/selectors';
|
|
13
|
-
|
|
14
|
-
interface PluginSettingsModalProps {
|
|
15
|
-
id: string;
|
|
16
|
-
onClose: () => void;
|
|
17
|
-
open?: boolean;
|
|
18
|
-
schema: any;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
const PluginSettingsModal = memo<PluginSettingsModalProps>(({ schema, onClose, id, open }) => {
|
|
22
|
-
const pluginMeta = useToolStore(pluginSelectors.getPluginMetaById(id), isEqual);
|
|
23
|
-
|
|
24
|
-
const { t } = useTranslation('plugin');
|
|
25
|
-
const theme = useTheme();
|
|
26
|
-
return (
|
|
27
|
-
<Modal
|
|
28
|
-
cancelText={t('cancel', { ns: 'common' })}
|
|
29
|
-
okText={t('ok', { ns: 'common' })}
|
|
30
|
-
onCancel={onClose}
|
|
31
|
-
onOk={() => {
|
|
32
|
-
onClose();
|
|
33
|
-
}}
|
|
34
|
-
open={open}
|
|
35
|
-
title={t('setting')}
|
|
36
|
-
width={600}
|
|
37
|
-
>
|
|
38
|
-
<MobilePadding>
|
|
39
|
-
<Center gap={16}>
|
|
40
|
-
<Avatar
|
|
41
|
-
avatar={pluginHelpers.getPluginAvatar(pluginMeta) || '⚙️'}
|
|
42
|
-
background={theme.colorFillContent}
|
|
43
|
-
gap={12}
|
|
44
|
-
size={64}
|
|
45
|
-
/>
|
|
46
|
-
|
|
47
|
-
<Flexbox style={{ fontSize: 20 }}>{pluginHelpers.getPluginTitle(pluginMeta)}</Flexbox>
|
|
48
|
-
<Typography.Text type={'secondary'}>
|
|
49
|
-
{pluginHelpers.getPluginDesc(pluginMeta)}
|
|
50
|
-
</Typography.Text>
|
|
51
|
-
<Divider style={{ marginBottom: 0, marginTop: 8 }} />
|
|
52
|
-
{schema && <PluginSettingsConfig id={id} schema={schema} />}
|
|
53
|
-
</Center>
|
|
54
|
-
</MobilePadding>
|
|
55
|
-
</Modal>
|
|
56
|
-
);
|
|
57
|
-
});
|
|
58
|
-
|
|
59
|
-
export default PluginSettingsModal;
|
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
import { LobeChatPluginMeta } from '@lobehub/chat-plugin-sdk';
|
|
2
|
-
import { Avatar, Icon, Tag } from '@lobehub/ui';
|
|
3
|
-
import { Button } from 'antd';
|
|
4
|
-
import { createStyles, useResponsive } from 'antd-style';
|
|
5
|
-
import { BadgeCheck, CircleUser } from 'lucide-react';
|
|
6
|
-
import Link from 'next/link';
|
|
7
|
-
import { memo } from 'react';
|
|
8
|
-
import { useTranslation } from 'react-i18next';
|
|
9
|
-
import { Flexbox } from 'react-layout-kit';
|
|
10
|
-
|
|
11
|
-
import { useToolStore } from '@/store/tool';
|
|
12
|
-
import { pluginSelectors, pluginStoreSelectors } from '@/store/tool/selectors';
|
|
13
|
-
|
|
14
|
-
import PluginSettings from './PluginSettings';
|
|
15
|
-
|
|
16
|
-
const useStyles = createStyles(({ css, token }) => ({
|
|
17
|
-
desc: css`
|
|
18
|
-
color: ${token.colorTextDescription};
|
|
19
|
-
`,
|
|
20
|
-
link: css`
|
|
21
|
-
color: ${token.colorText};
|
|
22
|
-
`,
|
|
23
|
-
tag: css`
|
|
24
|
-
color: ${token.colorTextSecondary};
|
|
25
|
-
`,
|
|
26
|
-
title: css`
|
|
27
|
-
font-size: ${token.fontSizeLG}px;
|
|
28
|
-
font-weight: bold;
|
|
29
|
-
line-height: 2;
|
|
30
|
-
`,
|
|
31
|
-
}));
|
|
32
|
-
const PluginItem = memo<LobeChatPluginMeta>(({ identifier, homepage, author, meta }) => {
|
|
33
|
-
const [installed, installing, installPlugin, unInstallPlugin] = useToolStore((s) => [
|
|
34
|
-
pluginSelectors.isPluginInstalled(identifier)(s),
|
|
35
|
-
pluginStoreSelectors.isPluginInstallLoading(identifier)(s),
|
|
36
|
-
s.installPlugin,
|
|
37
|
-
s.uninstallPlugin,
|
|
38
|
-
]);
|
|
39
|
-
const { mobile } = useResponsive();
|
|
40
|
-
const { styles } = useStyles();
|
|
41
|
-
|
|
42
|
-
const { t } = useTranslation('plugin');
|
|
43
|
-
return (
|
|
44
|
-
<Flexbox align={'center'} gap={8} horizontal justify={'space-between'}>
|
|
45
|
-
<Flexbox align={'center'} gap={8} horizontal>
|
|
46
|
-
<Avatar avatar={meta.avatar} size={mobile ? 40 : 56} style={{ flex: 'none' }} />
|
|
47
|
-
<Flexbox gap={4}>
|
|
48
|
-
<Flexbox align={'center'} gap={8} horizontal>
|
|
49
|
-
<Link className={styles.link} href={homepage} target={'_blank'}>
|
|
50
|
-
<div className={styles.title}>{meta.title}</div>
|
|
51
|
-
</Link>
|
|
52
|
-
|
|
53
|
-
<Tag
|
|
54
|
-
className={styles.tag}
|
|
55
|
-
icon={<Icon icon={author === 'LobeHub' ? BadgeCheck : CircleUser} />}
|
|
56
|
-
>
|
|
57
|
-
{author}
|
|
58
|
-
</Tag>
|
|
59
|
-
</Flexbox>
|
|
60
|
-
<div className={styles.desc}>{meta.description} </div>
|
|
61
|
-
</Flexbox>
|
|
62
|
-
</Flexbox>
|
|
63
|
-
<Flexbox align={'center'} gap={8} horizontal>
|
|
64
|
-
<PluginSettings identifier={identifier} />
|
|
65
|
-
<Button
|
|
66
|
-
loading={installing}
|
|
67
|
-
onClick={() => {
|
|
68
|
-
if (installed) {
|
|
69
|
-
unInstallPlugin(identifier);
|
|
70
|
-
} else installPlugin(identifier);
|
|
71
|
-
}}
|
|
72
|
-
size={mobile ? 'small' : undefined}
|
|
73
|
-
type={installed ? 'default' : 'primary'}
|
|
74
|
-
>
|
|
75
|
-
{t(installed ? 'store.uninstall' : 'store.install')}
|
|
76
|
-
</Button>
|
|
77
|
-
</Flexbox>
|
|
78
|
-
</Flexbox>
|
|
79
|
-
);
|
|
80
|
-
});
|
|
81
|
-
|
|
82
|
-
export default PluginItem;
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
import { ActionIcon } from '@lobehub/ui';
|
|
2
|
-
import { Settings2 } from 'lucide-react';
|
|
3
|
-
import { memo, useState } from 'react';
|
|
4
|
-
import { useTranslation } from 'react-i18next';
|
|
5
|
-
|
|
6
|
-
import PluginSettingsModal from '@/features/PluginSettingsModal';
|
|
7
|
-
import { useToolStore } from '@/store/tool';
|
|
8
|
-
import { pluginSelectors } from '@/store/tool/selectors';
|
|
9
|
-
|
|
10
|
-
const PluginSettings = memo<{ identifier: string }>(({ identifier }) => {
|
|
11
|
-
const { t } = useTranslation('setting');
|
|
12
|
-
|
|
13
|
-
const [open, setOpen] = useState(false);
|
|
14
|
-
|
|
15
|
-
const plugin = useToolStore(pluginSelectors.getPluginManifestById(identifier));
|
|
16
|
-
|
|
17
|
-
if (!plugin?.settings) return null;
|
|
18
|
-
|
|
19
|
-
return (
|
|
20
|
-
<>
|
|
21
|
-
<ActionIcon
|
|
22
|
-
icon={Settings2}
|
|
23
|
-
onClick={() => {
|
|
24
|
-
setOpen(true);
|
|
25
|
-
}}
|
|
26
|
-
title={t('plugin.settings.tooltip')}
|
|
27
|
-
/>
|
|
28
|
-
<PluginSettingsModal
|
|
29
|
-
id={identifier}
|
|
30
|
-
onClose={() => {
|
|
31
|
-
setOpen(false);
|
|
32
|
-
}}
|
|
33
|
-
open={open}
|
|
34
|
-
schema={plugin.settings}
|
|
35
|
-
/>
|
|
36
|
-
</>
|
|
37
|
-
);
|
|
38
|
-
});
|
|
39
|
-
|
|
40
|
-
export default PluginSettings;
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
const VERSION_URL = 'https://registry.npmmirror.com/@lobehub/chat';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* get latest version from npm
|
|
5
|
-
*/
|
|
6
|
-
export const featLatestVersion = async (): Promise<string> => {
|
|
7
|
-
const res = await fetch(VERSION_URL);
|
|
8
|
-
const data = await res.json();
|
|
9
|
-
|
|
10
|
-
return data['dist-tags']?.latest;
|
|
11
|
-
};
|
package/src/services/shareGPT.ts
DELETED
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import { ShareGPTConversation } from '@/types/share';
|
|
2
|
-
import { parseMarkdown } from '@/utils/parseMarkdown';
|
|
3
|
-
|
|
4
|
-
const SHAREGPT_URL = 'https://sharegpt.com/api/conversations';
|
|
5
|
-
|
|
6
|
-
export const genShareGPTUrl = async (conversation: ShareGPTConversation) => {
|
|
7
|
-
const items = [];
|
|
8
|
-
|
|
9
|
-
for (const item of conversation.items) {
|
|
10
|
-
items.push({
|
|
11
|
-
from: item.from,
|
|
12
|
-
value: item.from === 'gpt' ? await parseMarkdown(item.value) : item.value,
|
|
13
|
-
});
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
const res = await fetch(SHAREGPT_URL, {
|
|
17
|
-
body: JSON.stringify({ ...conversation, items }),
|
|
18
|
-
headers: {
|
|
19
|
-
'Content-Type': 'application/json',
|
|
20
|
-
},
|
|
21
|
-
method: 'POST',
|
|
22
|
-
});
|
|
23
|
-
|
|
24
|
-
const { id } = await res.json();
|
|
25
|
-
|
|
26
|
-
// short link to the ShareGPT post
|
|
27
|
-
return `https://shareg.pt/${id}`;
|
|
28
|
-
};
|