@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.
Files changed (148) hide show
  1. package/.env.example +1 -1
  2. package/.i18nrc.js +1 -0
  3. package/CHANGELOG.md +84 -0
  4. package/README.md +2 -2
  5. package/README.zh-CN.md +2 -2
  6. package/docs/Deployment/Environment-Variable.md +1 -1
  7. package/docs/Deployment/Environment-Variable.zh-CN.md +1 -1
  8. package/docs/Deployment/Upstream-Sync.md +1 -1
  9. package/docs/Deployment/Upstream-Sync.zh-CN.md +1 -1
  10. package/docs/Home.md +26 -26
  11. package/docs/Plugins/Plugin-Development.md +1 -1
  12. package/docs/Plugins/Plugin-Development.zh-CN.md +1 -1
  13. package/docs/_Sidebar.md +20 -20
  14. package/locales/en_US/chat.json +12 -12
  15. package/locales/en_US/common.json +13 -13
  16. package/locales/en_US/error.json +16 -14
  17. package/locales/en_US/market.json +2 -2
  18. package/locales/en_US/migration.json +4 -4
  19. package/locales/en_US/plugin.json +75 -38
  20. package/locales/en_US/setting.json +7 -7
  21. package/locales/fr_FR/chat.json +11 -11
  22. package/locales/fr_FR/common.json +14 -14
  23. package/locales/fr_FR/error.json +12 -10
  24. package/locales/fr_FR/plugin.json +42 -5
  25. package/locales/fr_FR/setting.json +12 -12
  26. package/locales/fr_FR/welcome.json +3 -3
  27. package/locales/ja_JP/chat.json +1 -1
  28. package/locales/ja_JP/common.json +3 -3
  29. package/locales/ja_JP/error.json +16 -14
  30. package/locales/ja_JP/migration.json +4 -4
  31. package/locales/ja_JP/plugin.json +70 -33
  32. package/locales/ja_JP/setting.json +1 -1
  33. package/locales/ko_KR/chat.json +1 -1
  34. package/locales/ko_KR/common.json +3 -3
  35. package/locales/ko_KR/error.json +16 -14
  36. package/locales/ko_KR/migration.json +4 -4
  37. package/locales/ko_KR/plugin.json +71 -34
  38. package/locales/ko_KR/setting.json +1 -1
  39. package/locales/ru_RU/chat.json +1 -1
  40. package/locales/ru_RU/common.json +3 -3
  41. package/locales/ru_RU/error.json +16 -14
  42. package/locales/ru_RU/market.json +2 -2
  43. package/locales/ru_RU/migration.json +4 -4
  44. package/locales/ru_RU/plugin.json +71 -34
  45. package/locales/ru_RU/setting.json +1 -1
  46. package/locales/zh_CN/chat.json +1 -1
  47. package/locales/zh_CN/common.json +1 -1
  48. package/locales/zh_CN/error.json +2 -0
  49. package/locales/zh_CN/plugin.json +42 -5
  50. package/locales/zh_CN/setting.json +1 -1
  51. package/locales/zh_TW/chat.json +1 -1
  52. package/locales/zh_TW/common.json +3 -3
  53. package/locales/zh_TW/error.json +16 -14
  54. package/locales/zh_TW/market.json +2 -2
  55. package/locales/zh_TW/migration.json +4 -4
  56. package/locales/zh_TW/plugin.json +98 -61
  57. package/locales/zh_TW/setting.json +1 -1
  58. package/package.json +3 -1
  59. package/scripts/docsWorkflow/index.ts +5 -2
  60. package/scripts/docsWorkflow/toc.ts +2 -2
  61. package/scripts/i18nWorkflow/genDiff.ts +7 -8
  62. package/scripts/i18nWorkflow/utils.ts +0 -14
  63. package/scripts/readmeWorkflow/syncPluginIndex.ts +9 -11
  64. package/src/app/api/plugins/route.ts +2 -4
  65. package/src/app/api/proxy/route.ts +10 -0
  66. package/src/app/chat/features/ChatInput/ActionBar/Tools/ToolItem.tsx +3 -8
  67. package/src/app/chat/features/ChatInput/ActionBar/Tools/index.tsx +3 -3
  68. package/src/app/chat/features/Conversation/ChatList/Error/index.tsx +6 -0
  69. package/src/app/chat/features/Conversation/ChatList/Messages/Function.tsx +1 -1
  70. package/src/app/chat/features/Conversation/ChatList/Plugins/Inspector/Settings.tsx +7 -5
  71. package/src/app/chat/features/Conversation/ChatList/Plugins/Inspector/index.tsx +2 -2
  72. package/src/app/chat/features/Conversation/ChatList/Plugins/Render/DefaultType/index.tsx +6 -4
  73. package/src/app/chat/features/Conversation/ChatList/Plugins/Render/index.tsx +2 -2
  74. package/src/app/chat/features/Migration/ExportConfigButton.tsx +1 -1
  75. package/src/app/market/features/AgentDetailContent/AgentInfo/index.tsx +1 -0
  76. package/src/app/market/features/AgentDetailContent/AgentInfo/style.ts +1 -9
  77. package/src/app/settings/common/Common.tsx +5 -7
  78. package/src/app/settings/features/UpgradeAlert.tsx +2 -2
  79. package/src/components/FileList/FileItem.tsx +4 -2
  80. package/src/components/HotKeys/index.tsx +5 -4
  81. package/src/const/plugin.ts +1 -0
  82. package/src/const/url.ts +1 -0
  83. package/src/const/version.ts +0 -3
  84. package/src/features/AgentSetting/AgentPlugin/AddPluginButton.tsx +2 -2
  85. package/src/features/AgentSetting/AgentPlugin/LocalPluginItem.tsx +19 -53
  86. package/src/features/AgentSetting/AgentPlugin/index.tsx +5 -11
  87. package/src/features/AgentSetting/store/initialState.ts +1 -1
  88. package/src/features/PluginDetailModal/APIs.tsx +44 -0
  89. package/src/features/PluginDetailModal/Meta.tsx +59 -0
  90. package/src/features/PluginDetailModal/index.tsx +79 -0
  91. package/src/features/PluginDevModal/PluginPreview.tsx +8 -10
  92. package/src/features/PluginDevModal/UrlManifestForm.tsx +131 -0
  93. package/src/features/PluginDevModal/index.tsx +31 -32
  94. package/src/features/PluginSettings/index.tsx +1 -1
  95. package/src/features/PluginStore/AddPluginButton.tsx +47 -0
  96. package/src/features/PluginStore/InstalledPluginList.tsx +54 -0
  97. package/src/features/PluginStore/OnlineList.tsx +95 -0
  98. package/src/features/PluginStore/PluginItem/Action.tsx +118 -0
  99. package/src/features/PluginStore/PluginItem/EditCustomPlugin.tsx +50 -0
  100. package/src/features/PluginStore/PluginItem/PluginTag.tsx +58 -0
  101. package/src/features/PluginStore/PluginItem/index.tsx +73 -0
  102. package/src/features/PluginStore/index.tsx +20 -92
  103. package/src/hooks/usePlatform.ts +15 -0
  104. package/src/locales/default/chat.ts +1 -1
  105. package/src/locales/default/common.ts +1 -1
  106. package/src/locales/default/error.ts +2 -0
  107. package/src/locales/default/plugin.ts +41 -4
  108. package/src/locales/default/setting.ts +1 -1
  109. package/src/services/__tests__/__snapshots__/plugin.test.ts.snap +154 -0
  110. package/src/services/__tests__/chat.test.ts +1 -1
  111. package/src/services/__tests__/global.test.ts +57 -0
  112. package/src/services/__tests__/openai/OpenAPI_V3.json +245 -0
  113. package/src/services/__tests__/openai/plugin.json +22 -0
  114. package/src/services/__tests__/plugin.test.ts +90 -1
  115. package/src/services/__tests__/share.test.ts +86 -0
  116. package/src/services/_url.ts +2 -0
  117. package/src/services/global.ts +15 -0
  118. package/src/services/plugin.ts +99 -15
  119. package/src/services/share.ts +34 -0
  120. package/src/store/chat/actions/enhance.test.ts +15 -15
  121. package/src/store/chat/actions/message.test.ts +3 -2
  122. package/src/store/chat/actions/plugin.test.ts +281 -0
  123. package/src/store/chat/actions/plugin.ts +22 -3
  124. package/src/store/chat/actions/share.ts +2 -2
  125. package/src/store/chat/actions/topic.test.ts +12 -4
  126. package/src/store/global/slices/common.ts +2 -2
  127. package/src/store/session/selectors.ts +1 -1
  128. package/src/store/session/slices/agent/selectors.ts +1 -1
  129. package/src/store/tool/helpers.ts +8 -1
  130. package/src/store/tool/slices/customPlugin/action.ts +4 -1
  131. package/src/store/tool/slices/plugin/selectors.test.ts +22 -3
  132. package/src/store/tool/slices/plugin/selectors.ts +24 -5
  133. package/src/store/tool/slices/store/selectors.test.ts +18 -1
  134. package/src/store/tool/slices/store/selectors.ts +14 -3
  135. package/src/styles/antdOverride.ts +7 -0
  136. package/src/types/openai/chat.ts +0 -1
  137. package/src/types/openai/plugin.ts +57 -0
  138. package/src/types/tool/index.ts +1 -2
  139. package/src/types/tool/plugin.ts +13 -1
  140. package/src/types/tool/tool.ts +1 -0
  141. package/src/types/translate.ts +0 -1
  142. package/src/utils/platform.ts +8 -5
  143. package/src/features/PluginDevModal/UrlModeForm.tsx +0 -98
  144. package/src/features/PluginSettingsModal/index.tsx +0 -59
  145. package/src/features/PluginStore/PluginItem.tsx +0 -82
  146. package/src/features/PluginStore/PluginSettings.tsx +0 -40
  147. package/src/services/latestVersion.ts +0 -11
  148. 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(mockState.pluginStoreList);
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 s.pluginStoreList.filter((p) => installedPluginIds.has(p.identifier));
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
  `;
@@ -1,4 +1,3 @@
1
-
2
1
  import { LLMRoleType } from '@/types/llm';
3
2
 
4
3
  import { OpenAIFunctionCall } from './functionCall';
@@ -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
+ }
@@ -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;
@@ -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';
@@ -2,4 +2,3 @@ export interface Translate {
2
2
  from?: string;
3
3
  to: string;
4
4
  }
5
-
@@ -1,11 +1,14 @@
1
1
  import UAParser from 'ua-parser-js';
2
2
 
3
- export const getPlatform = () => {
3
+ const getPaser = () => {
4
4
  let ua = navigator.userAgent;
5
- return new UAParser(ua).getOS();
5
+ return new UAParser(ua);
6
+ };
7
+
8
+ export const getPlatform = () => {
9
+ return getPaser().getOS().name;
6
10
  };
7
11
 
8
- export const isApplePlatform = () => {
9
- const platform = getPlatform().name;
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
- };
@@ -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
- };