@lobehub/chat 0.81.0 → 0.82.2

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 (83) hide show
  1. package/CHANGELOG.md +75 -0
  2. package/README.md +22 -6
  3. package/README.zh-CN.md +21 -5
  4. package/docs/Environment-Variable.md +45 -9
  5. package/docs/Environment-Variable.zh-CN.md +3 -6
  6. package/locales/en_US/common.json +13 -1
  7. package/locales/ru_RU/common.json +13 -1
  8. package/locales/zh_CN/common.json +13 -1
  9. package/locales/zh_TW/common.json +13 -1
  10. package/package.json +6 -3
  11. package/public/images/screenshot_background.webp +0 -0
  12. package/public/manifest.json +2 -16
  13. package/src/app/chat/features/Conversation/ChatList/Error/InvalidAccess.tsx +16 -6
  14. package/src/app/chat/features/Header/Mobile.tsx +12 -7
  15. package/src/app/chat/features/Header/ShareButton/Inner.tsx +114 -14
  16. package/src/app/chat/features/Header/ShareButton/Preview.tsx +140 -0
  17. package/src/app/chat/features/Header/ShareButton/index.tsx +12 -2
  18. package/src/app/chat/features/Header/ShareButton/style.ts +71 -0
  19. package/src/app/chat/features/SessionList/Header/Desktop.tsx +2 -4
  20. package/src/app/chat/features/SessionList/Header/Mobile.tsx +15 -14
  21. package/src/app/chat/features/Sidebar/Mobile.tsx +3 -17
  22. package/src/app/chat/layout.desktop.tsx +2 -1
  23. package/src/app/chat/layout.mobile.tsx +2 -1
  24. package/src/app/chat/settings/features/Header/index.tsx +3 -3
  25. package/src/app/chat/settings/layout.mobile.tsx +1 -8
  26. package/src/app/market/features/AgentCard/AgentCardBanner.tsx +2 -1
  27. package/src/app/market/features/Header/Mobile.tsx +2 -21
  28. package/src/app/market/features/SideBar/AgentInfo/Header.tsx +2 -1
  29. package/src/app/market/features/SideBar/AgentInfo/index.tsx +10 -2
  30. package/src/app/market/features/SideBar/Mobile.tsx +3 -17
  31. package/src/app/market/layout.desktop.tsx +2 -1
  32. package/src/app/market/layout.mobile.tsx +2 -1
  33. package/src/app/settings/agent/index.tsx +20 -0
  34. package/src/app/settings/agent/page.tsx +7 -0
  35. package/src/app/settings/{features/Settings → common}/Common.tsx +1 -1
  36. package/src/app/settings/common/index.tsx +20 -0
  37. package/src/app/settings/common/page.tsx +7 -0
  38. package/src/app/settings/features/Header/Desktop.tsx +9 -2
  39. package/src/app/settings/features/Header/Mobile.tsx +5 -2
  40. package/src/app/settings/features/SideBar/Item.tsx +39 -0
  41. package/src/app/settings/features/SideBar/List.tsx +30 -0
  42. package/src/app/settings/features/SideBar/index.tsx +38 -0
  43. package/src/app/settings/index.tsx +5 -7
  44. package/src/app/settings/layout.desktop.tsx +6 -2
  45. package/src/app/settings/layout.mobile.tsx +1 -3
  46. package/src/app/settings/{features/Settings → llm}/LLM/index.tsx +4 -2
  47. package/src/app/settings/llm/index.tsx +20 -0
  48. package/src/app/settings/llm/page.tsx +7 -0
  49. package/src/app/settings/mobile/ExtraList.tsx +61 -0
  50. package/src/app/settings/mobile/index.tsx +43 -0
  51. package/src/app/settings/mobile/page.tsx +7 -0
  52. package/src/app/settings/page.tsx +1 -7
  53. package/src/components/MobilePadding/index.tsx +32 -0
  54. package/src/const/layoutTokens.ts +1 -0
  55. package/src/features/AgentSetting/AgentMeta/index.tsx +0 -1
  56. package/src/features/AgentSetting/AgentPlugin/MarketSettingModal.tsx +29 -16
  57. package/src/features/AvatarWithUpload/index.tsx +23 -45
  58. package/src/features/MobileTabBar/index.tsx +15 -3
  59. package/src/features/PluginDevModal/PluginPreview.tsx +11 -4
  60. package/src/features/PluginDevModal/index.tsx +14 -10
  61. package/src/features/SideBar/BottomActions.tsx +3 -3
  62. package/src/features/SideBar/TopActions.tsx +5 -4
  63. package/src/features/SideBar/index.tsx +1 -1
  64. package/src/locales/create.ts +5 -3
  65. package/src/locales/default/common.ts +13 -1
  66. package/src/locales/default/plugin.ts +2 -1
  67. package/src/services/shareGPT.ts +11 -1
  68. package/src/store/global/hooks/useSwitchSettingsOnInit.ts +9 -0
  69. package/src/store/global/initialState.ts +13 -4
  70. package/src/store/global/store.ts +0 -4
  71. package/src/store/session/slices/chat/actions/share.ts +73 -39
  72. package/src/styles/antdOverride.ts +2 -26
  73. package/src/styles/global.ts +9 -0
  74. package/src/utils/imageToBase64.ts +37 -0
  75. package/src/utils/parseMarkdown.ts +9 -0
  76. package/public/icons/icon-maskable-192x192.png +0 -0
  77. package/public/icons/icon-maskable-512x512.png +0 -0
  78. package/src/app/settings/features/Banner/index.tsx +0 -94
  79. package/src/app/settings/features/Settings/index.tsx +0 -53
  80. /package/src/app/settings/{features/Settings → agent}/Agent.tsx +0 -0
  81. /package/src/app/settings/{features/Settings → llm}/LLM/Checker.tsx +0 -0
  82. /package/src/app/settings/{features/Settings → llm}/LLM/ModelList.tsx +0 -0
  83. /package/src/app/settings/{features/Settings → llm}/LLM/getModelList.ts +0 -0
@@ -1,3 +1,4 @@
1
+ import dayjs from 'dayjs';
1
2
  import { produce } from 'immer';
2
3
  import { StateCreator } from 'zustand/vanilla';
3
4
 
@@ -9,9 +10,45 @@ import { agentSelectors } from '../../agentConfig';
9
10
  import { sessionSelectors } from '../../session/selectors';
10
11
  import { chatSelectors } from '../selectors';
11
12
 
13
+ interface ShareMessage {
14
+ from: 'human' | 'gpt';
15
+ value: string;
16
+ }
17
+ export const AVATAR =
18
+ 'data:image/webp;base64,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';
19
+
20
+ const Footer: ShareMessage = {
21
+ from: 'gpt',
22
+ value: `Share from [**🤯 LobeChat**](https://github.com/lobehub/lobe-chat) - ${dayjs().format(
23
+ 'YYYY-MM-DD',
24
+ )}`,
25
+ };
26
+
27
+ const PLUGIN_INFO = (plugin: {
28
+ apiName: string;
29
+ content: string;
30
+ identifier: string;
31
+ }): ShareMessage => ({
32
+ from: 'gpt',
33
+ value: [
34
+ `**🧩 Function Calling Plugin**`,
35
+ `- Identifier: \`${plugin.identifier}\``,
36
+ `- API name: \`${plugin.apiName}\``,
37
+ `- Result:`,
38
+ ``,
39
+ '```json',
40
+ plugin.content,
41
+ '```',
42
+ ].join('\n'),
43
+ });
44
+
12
45
  // const t = setNamespace('chat/share');
13
46
  export interface ShareAction {
14
- shareToShareGPT: () => void;
47
+ shareToShareGPT: (props: {
48
+ avatar?: string;
49
+ withPluginInfo?: boolean;
50
+ withSystemRole?: boolean;
51
+ }) => void;
15
52
  }
16
53
 
17
54
  export const chatShare: StateCreator<
@@ -20,72 +57,69 @@ export const chatShare: StateCreator<
20
57
  [],
21
58
  ShareAction
22
59
  > = (set, get) => ({
23
- // genShareUrl: () => {
24
- // const session = sessionSelectors.currentSession(get());
25
- // if (!session) return '';
26
- //
27
- // const agent = session.config;
28
- // return genShareMessagesUrl(session.chats, agent.systemRole);
29
- // },
30
- shareToShareGPT: async () => {
60
+ shareToShareGPT: async ({ withSystemRole, withPluginInfo, avatar }) => {
31
61
  const session = sessionSelectors.currentSession(get());
32
62
  if (!session) return;
33
63
  const messages = chatSelectors.currentChats(get());
34
64
  const config = agentSelectors.currentAgentConfig(get());
65
+ const meta = agentSelectors.currentAgentMeta(get());
35
66
 
36
67
  const defaultMsg: ShareGPTConversation['items'] = [];
37
-
68
+ const showSystemRole = withSystemRole && !!config.systemRole;
38
69
  const shareMsgs = produce(defaultMsg, (draft) => {
39
- if (!!config.systemRole) {
40
- draft.push({
41
- from: 'human',
42
- value: `-------------- ### This is a system settings | 这是一条系统设定
43
-
44
- ${config.systemRole}`,
45
- });
46
- }
70
+ draft.push({
71
+ from: 'gpt',
72
+ value: [
73
+ `${meta.avatar} **${meta.title}** - ${meta.description}`,
74
+ showSystemRole && '---',
75
+ showSystemRole && config.systemRole,
76
+ ]
77
+ .filter(Boolean)
78
+ .join('\n\n'),
79
+ });
47
80
 
48
81
  for (const i of messages) {
49
82
  switch (i.role) {
50
- case 'user':
51
- default: {
52
- draft.push({ from: 'human', value: i.content });
53
- break;
54
- }
55
-
56
83
  case 'assistant': {
57
84
  draft.push({ from: 'gpt', value: i.content });
58
85
  break;
59
86
  }
60
87
  case 'function': {
61
- draft.push({
62
- from: 'gpt',
63
- value: `-------------- ### This is a function call | 这是一次插件调用
64
- plugin name: ${i.plugin?.identifier}
65
- function call name: ${i.plugin?.apiName}
66
- result:
67
- \`\`\`json
68
- ${i.content}
69
- \`\`\``,
70
- });
88
+ if (withPluginInfo)
89
+ draft.push(
90
+ PLUGIN_INFO({
91
+ apiName: i.plugin?.apiName || 'undefined',
92
+ content: i.content,
93
+ identifier: i.plugin?.identifier || 'undefined',
94
+ }),
95
+ );
96
+ break;
97
+ }
98
+ case 'user': {
99
+ draft.push({ from: 'human', value: i.content });
71
100
  break;
72
101
  }
73
102
  }
74
103
  }
75
104
 
76
- draft.push({
77
- from: 'human',
78
- value: 'Share from [LobeChat](https://github.com/lobehub/lobe-chat)',
79
- });
105
+ draft.push(Footer);
80
106
  });
81
107
 
82
108
  set({ shareLoading: true });
109
+
83
110
  const res = await genShareGPTUrl({
84
- avatarUrl: 'https://npm.elemecdn.com/@lobehub/assets-logo/assets/logo-3d.webp',
111
+ avatarUrl: avatar || AVATAR,
85
112
  items: shareMsgs,
86
113
  });
87
114
  set({ shareLoading: false });
88
115
 
89
116
  window.open(res, '_blank');
90
117
  },
118
+ // genShareUrl: () => {
119
+ // const session = sessionSelectors.currentSession(get());
120
+ // if (!session) return '';
121
+ //
122
+ // const agent = session.config;
123
+ // return genShareMessagesUrl(session.chats, agent.systemRole);
124
+ // },
91
125
  });
@@ -1,31 +1,7 @@
1
1
  import { Theme, css } from 'antd-style';
2
- import { readableColor } from 'polished';
3
2
 
4
- export default ({ token, prefixCls }: { prefixCls: string; token: Theme }) => css`
5
- .${prefixCls}-btn {
6
- box-shadow: none;
7
- }
8
-
9
- .${prefixCls}-popover {
3
+ export default ({ token }: { prefixCls: string; token: Theme }) => css`
4
+ .${token.prefixCls}-popover {
10
5
  z-index: 1100;
11
6
  }
12
-
13
- .${prefixCls}-slider-track, .${prefixCls}-tabs-ink-bar, .${prefixCls}-switch-checked {
14
- background: ${token.colorPrimary} !important;
15
- }
16
-
17
- .${prefixCls}-btn-primary:not(.${prefixCls}-btn-dangerous) {
18
- color: ${readableColor(token.colorPrimary)};
19
- background: ${token.colorPrimary};
20
-
21
- &:hover {
22
- color: ${readableColor(token.colorPrimary)} !important;
23
- background: ${token.colorPrimaryHover} !important;
24
- }
25
-
26
- &:active {
27
- color: ${readableColor(token.colorPrimaryActive)} !important;
28
- background: ${token.colorPrimaryActive} !important;
29
- }
30
- }
31
7
  `;
@@ -20,4 +20,13 @@ export default ({ prefixCls }: { prefixCls: string }) => css`
20
20
  p {
21
21
  margin-bottom: 0;
22
22
  }
23
+
24
+ @media (max-width: 575px) {
25
+ * {
26
+ ::-webkit-scrollbar {
27
+ width: 0;
28
+ height: 0;
29
+ }
30
+ }
31
+ }
23
32
  `;
@@ -0,0 +1,37 @@
1
+ export const imageToBase64 = ({
2
+ size,
3
+ img,
4
+ type = 'image/webp',
5
+ }: {
6
+ img: HTMLImageElement;
7
+ size: number;
8
+ type?: string;
9
+ }) => {
10
+ const canvas = document.createElement('canvas');
11
+ const ctx = canvas.getContext('2d') as CanvasRenderingContext2D;
12
+ let startX = 0;
13
+ let startY = 0;
14
+
15
+ if (img.width > img.height) {
16
+ startX = (img.width - img.height) / 2;
17
+ } else {
18
+ startY = (img.height - img.width) / 2;
19
+ }
20
+
21
+ canvas.width = size;
22
+ canvas.height = size;
23
+
24
+ ctx.drawImage(
25
+ img,
26
+ startX,
27
+ startY,
28
+ Math.min(img.width, img.height),
29
+ Math.min(img.width, img.height),
30
+ 0,
31
+ 0,
32
+ size,
33
+ size,
34
+ );
35
+
36
+ return canvas.toDataURL(type);
37
+ };
@@ -0,0 +1,9 @@
1
+ import { remark } from 'remark';
2
+ import remarkGfm from 'remark-gfm';
3
+ import remarkHtml from 'remark-html';
4
+
5
+ export const parseMarkdown = async (content: string) => {
6
+ const file = await remark().use(remarkGfm).use(remarkHtml).process(content.trim());
7
+
8
+ return String(file);
9
+ };
@@ -1,94 +0,0 @@
1
- import { GridBackground, Icon, Logo } from '@lobehub/ui';
2
- import { createStyles, useResponsive } from 'antd-style';
3
- import { PackageCheck } from 'lucide-react';
4
- import { rgba } from 'polished';
5
- import { ReactNode, memo } from 'react';
6
- import { Flexbox } from 'react-layout-kit';
7
-
8
- import pkg from '@/../package.json';
9
-
10
- const useStyles = createStyles(({ css, token, isDarkMode, prefixCls }) => ({
11
- background: css`
12
- position: absolute;
13
- bottom: -10%;
14
- left: 0;
15
- width: 100%;
16
- `,
17
- banner: css`
18
- position: relative;
19
-
20
- overflow: hidden;
21
-
22
- width: 100%;
23
- max-width: 1024px;
24
- height: 160px;
25
- padding: 4px;
26
-
27
- background: radial-gradient(
28
- 120% 120% at 20% 100%,
29
- ${isDarkMode ? rgba(token.colorBgContainer, 0.5) : token.colorBgContainer} 32%,
30
- ${isDarkMode ? token.colorPrimaryBgHover : rgba(token.colorPrimaryBgHover, 0.3)} 50%,
31
- ${isDarkMode ? token.colorPrimaryHover : rgba(token.colorPrimaryHover, 0.3)} 100%
32
- );
33
- border: 1px solid ${token.colorBorderSecondary};
34
- border-radius: ${token.borderRadiusLG}px;
35
- `,
36
- logo: css`
37
- position: absolute;
38
- top: 50%;
39
- left: 32px;
40
- transform: translateY(-50%);
41
- `,
42
- mobile: css`
43
- margin-top: -16px;
44
-
45
- .${prefixCls}-tabs-tab, .${prefixCls}-tabs-tab + .${prefixCls}-tabs-tab {
46
- margin: 4px 8px !important;
47
- }
48
- `,
49
- tag: css`
50
- position: absolute;
51
- top: 6px;
52
- right: 12px;
53
-
54
- font-family: ${token.fontFamilyCode};
55
- font-size: 12px;
56
- color: ${isDarkMode ? token.colorPrimaryBg : token.colorPrimaryActive};
57
-
58
- opacity: 0.5;
59
- `,
60
- }));
61
-
62
- const Banner = memo<{ nav: ReactNode }>(({ nav }) => {
63
- const { styles, theme } = useStyles();
64
- const { mobile } = useResponsive();
65
-
66
- if (mobile)
67
- return (
68
- <Flexbox align={'flex-end'} className={styles.mobile} horizontal justify={'center'}>
69
- {nav}
70
- </Flexbox>
71
- );
72
-
73
- return (
74
- <Flexbox align={'flex-end'} className={styles.banner} horizontal justify={'center'}>
75
- <GridBackground
76
- animation
77
- className={styles.background}
78
- colorBack={theme.colorFillSecondary}
79
- colorFront={theme.colorPrimary}
80
- random
81
- />
82
- {nav}
83
- <div className={styles.logo}>
84
- <Logo extra={'Chat'} type={'text'} />
85
- </div>
86
- <Flexbox align={'center'} className={styles.tag} gap={4} horizontal>
87
- <Icon icon={PackageCheck} />
88
- <div>{`${pkg.version}`}</div>
89
- </Flexbox>
90
- </Flexbox>
91
- );
92
- });
93
-
94
- export default Banner;
@@ -1,53 +0,0 @@
1
- import { TabsNav } from '@lobehub/ui';
2
- import { memo, useMemo } from 'react';
3
- import { useTranslation } from 'react-i18next';
4
- import { Center } from 'react-layout-kit';
5
-
6
- import { useGlobalStore } from '@/store/global';
7
-
8
- import Banner from '../Banner';
9
- import Agent from './Agent';
10
- import Common from './Common';
11
- import LLM from './LLM';
12
-
13
- const Settings = memo(() => {
14
- const { t } = useTranslation('setting');
15
-
16
- const [tab, setTab] = useGlobalStore((s) => [s.settingsTab, s.switchSettingTabs]);
17
-
18
- const content = useMemo(() => {
19
- switch (tab) {
20
- case 'llm': {
21
- return <LLM />;
22
- }
23
- case 'agent': {
24
- return <Agent />;
25
- }
26
- default:
27
- case 'common': {
28
- return <Common />;
29
- }
30
- }
31
- }, [tab]);
32
-
33
- return (
34
- <Center gap={16} width={'100%'}>
35
- <Banner
36
- nav={
37
- <TabsNav
38
- activeKey={tab}
39
- items={[
40
- { key: 'common', label: t('tab.common') },
41
- { key: 'llm', label: t('tab.llm') },
42
- { key: 'agent', label: t('tab.agent') },
43
- ]}
44
- onChange={(e) => setTab(e as any)}
45
- />
46
- }
47
- />
48
- {content}
49
- </Center>
50
- );
51
- });
52
-
53
- export default Settings;