@lobehub/chat 0.82.7 → 0.82.9
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 +42 -0
- package/next.config.mjs +6 -1
- package/package.json +5 -1
- package/src/app/chat/{features/Header → (desktop)/features/ChatHeader}/Desktop.tsx +2 -2
- package/src/app/chat/{features/Header → (desktop)/features/ChatHeader}/index.tsx +1 -1
- package/src/app/chat/(desktop)/features/ChatInput/index.tsx +22 -0
- package/src/app/chat/{features/SessionList/Header → (desktop)/features/SessionHeader}/Desktop.tsx +1 -1
- package/src/app/chat/{features/SessionList/Header → (desktop)/features/SessionHeader}/index.tsx +1 -1
- package/src/app/chat/{features → (desktop)/features}/SessionList/Desktop.tsx +1 -1
- package/src/app/chat/(desktop)/features/SessionList/index.tsx +20 -0
- package/src/app/chat/{features/Sidebar → (desktop)/features/SideBar}/Desktop.tsx +4 -4
- package/src/app/chat/(desktop)/features/SideBar/index.tsx +20 -0
- package/src/app/chat/(desktop)/index.tsx +24 -0
- package/src/app/chat/{layout.desktop.tsx → (desktop)/layout/Desktop.tsx} +4 -4
- package/src/app/chat/(desktop)/layout/index.tsx +25 -0
- package/src/app/chat/(mobile)/features/ChatHeader.tsx +1 -0
- package/src/app/chat/(mobile)/features/ChatInput.tsx +14 -0
- package/src/app/chat/(mobile)/features/SessionList.tsx +12 -0
- package/src/app/chat/(mobile)/features/Topics.tsx +12 -0
- package/src/app/chat/(mobile)/index.tsx +20 -0
- package/src/app/chat/(mobile)/layout.tsx +15 -0
- package/src/app/chat/(mobile)/mobile/page.tsx +21 -0
- package/src/app/chat/{features/Header → components/ChatHeader}/Mobile.tsx +2 -1
- package/src/app/chat/{features/Header → components/ChatHeader}/ShareButton/Preview.tsx +3 -3
- package/src/app/chat/{features/Conversation/Input → components/ChatInput}/ActionBar/Token.tsx +10 -7
- package/src/app/chat/{features/Conversation/Input → components/ChatInput}/index.tsx +30 -24
- package/src/app/chat/components/Inspector/index.tsx +17 -0
- package/src/app/chat/{features → components}/SessionList/Mobile.tsx +1 -1
- package/src/app/chat/{features → components}/SessionList/index.tsx +3 -10
- package/src/app/chat/features/Conversation/index.tsx +8 -4
- package/src/app/chat/features/PageTitle.tsx +19 -0
- package/src/app/chat/layout.tsx +14 -0
- package/src/app/chat/page.tsx +9 -4
- package/src/app/chat/settings/(desktop)/Header/index.tsx +13 -0
- package/src/app/chat/settings/{layout.desktop.tsx → (desktop)/layout.desktop.tsx} +5 -4
- package/src/app/chat/settings/(mobile)/Header.tsx +12 -0
- package/src/app/chat/settings/{layout.mobile.tsx → (mobile)/layout.mobile.tsx} +3 -1
- package/src/app/chat/settings/{features → components}/Header/index.tsx +4 -13
- package/src/app/chat/settings/layout.tsx +14 -0
- package/src/app/chat/settings/page.tsx +36 -5
- package/src/app/home/Redirect.tsx +29 -0
- package/src/app/home/index.tsx +18 -29
- package/src/app/market/features/SideBar/AgentInfo/TokenTag.tsx +4 -3
- package/src/app/metadata.ts +4 -1
- package/src/app/page.tsx +7 -3
- package/src/app/welcome/{layout.desktop.tsx → DesktopLayout/Desktop.tsx} +5 -4
- package/src/app/welcome/DesktopLayout/index.tsx +15 -0
- package/src/app/welcome/{layout.mobile.tsx → MobileLayout.tsx} +6 -3
- package/src/app/welcome/features/Banner/index.tsx +2 -0
- package/src/app/welcome/features/Footer/index.tsx +2 -0
- package/src/app/welcome/layout.tsx +22 -0
- package/src/app/welcome/page.tsx +10 -5
- package/src/components/PageTitle.tsx +11 -0
- package/src/features/AgentSetting/AgentPrompt/index.tsx +3 -6
- package/src/hooks/useTokenCount.ts +20 -0
- package/src/layout/AppMobileLayout.tsx +15 -24
- package/src/prompts/chat.ts +4 -2
- package/src/store/session/hooks/useEffectAfterHydrated.ts +11 -6
- package/src/store/session/slices/chat/actions/message.ts +1 -1
- package/src/store/session/slices/chat/actions/topic.ts +3 -3
- package/src/store/session/slices/chat/helpers.ts +3 -4
- package/src/store/session/slices/chat/selectors/chat.ts +5 -0
- package/src/store/session/slices/chat/selectors/index.ts +9 -5
- package/src/store/session/slices/session/action.ts +1 -1
- package/src/utils/responsive.ts +19 -0
- package/src/utils/tokenizer.ts +5 -0
- package/src/app/chat/features/Sidebar/index.tsx +0 -29
- package/src/app/chat/index.tsx +0 -54
- package/src/app/chat/layout.mobile.tsx +0 -20
- package/src/app/chat/mobile/index.tsx +0 -38
- package/src/app/chat/mobile/page.tsx +0 -7
- package/src/app/chat/settings/index.tsx +0 -51
- package/src/app/home/Loading.tsx +0 -23
- package/src/app/welcome/index.tsx +0 -39
- package/src/store/session/slices/chat/selectors/token.ts +0 -28
- /package/src/app/chat/{features/Conversation/Input → (desktop)/features/ChatInput}/Desktop.tsx +0 -0
- /package/src/app/chat/{features/SessionList/Header/Mobile.tsx → (mobile)/features/SessionHeader.tsx} +0 -0
- /package/src/app/chat/{features/Header → components/ChatHeader}/PluginTag/PluginStatus.tsx +0 -0
- /package/src/app/chat/{features/Header → components/ChatHeader}/PluginTag/index.tsx +0 -0
- /package/src/app/chat/{features/Header → components/ChatHeader}/ShareButton/Inner.tsx +0 -0
- /package/src/app/chat/{features/Header → components/ChatHeader}/ShareButton/index.tsx +0 -0
- /package/src/app/chat/{features/Header → components/ChatHeader}/ShareButton/style.ts +0 -0
- /package/src/app/chat/{features/Conversation/Input → components/ChatInput}/ActionBar/ActionLeft.tsx +0 -0
- /package/src/app/chat/{features/Conversation/Input → components/ChatInput}/ActionBar/ActionRight.tsx +0 -0
- /package/src/app/chat/{features/Conversation/Input → components/ChatInput}/Footer/SaveTopic.tsx +0 -0
- /package/src/app/chat/{features/Conversation/Input → components/ChatInput}/Footer/index.tsx +0 -0
- /package/src/app/chat/{features/Conversation/Input → components/ChatInput}/Mobile.tsx +0 -0
- /package/src/app/chat/{features/Sidebar → components/Inspector}/Mobile.tsx +0 -0
- /package/src/app/chat/{features/Sidebar → components/Inspector}/SystemRole/Header.tsx +0 -0
- /package/src/app/chat/{features/Sidebar → components/Inspector}/SystemRole/index.tsx +0 -0
- /package/src/app/chat/{features/Sidebar → components/Inspector}/SystemRole/style.ts +0 -0
- /package/src/app/chat/{features/Sidebar → components/Inspector}/Topic/DefaultContent.tsx +0 -0
- /package/src/app/chat/{features/Sidebar → components/Inspector}/Topic/SkeletonList.tsx +0 -0
- /package/src/app/chat/{features/Sidebar → components/Inspector}/Topic/TopicContent.tsx +0 -0
- /package/src/app/chat/{features/Sidebar → components/Inspector}/Topic/TopicItem.tsx +0 -0
- /package/src/app/chat/{features/Sidebar → components/Inspector}/Topic/index.tsx +0 -0
- /package/src/app/chat/{features/Sidebar → components/Inspector}/TopicSearchBar/index.tsx +0 -0
- /package/src/app/chat/{features → components}/SessionList/CollapseGroup/index.tsx +0 -0
- /package/src/app/chat/{features → components}/SessionList/Inbox/index.tsx +0 -0
- /package/src/app/chat/{features → components}/SessionList/List/AddButton.tsx +0 -0
- /package/src/app/chat/{features → components}/SessionList/List/Item/Actions.tsx +0 -0
- /package/src/app/chat/{features → components}/SessionList/List/Item/index.tsx +0 -0
- /package/src/app/chat/{features → components}/SessionList/List/SkeletonList.tsx +0 -0
- /package/src/app/chat/{features → components}/SessionList/List/index.tsx +0 -0
- /package/src/app/chat/settings/{features → (desktop)}/Header/Desktop.tsx +0 -0
- /package/src/app/chat/settings/{features → components}/Header/Mobile.tsx +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { BackBottom } from '@lobehub/ui';
|
|
2
2
|
import { createStyles } from 'antd-style';
|
|
3
|
-
import { memo, useRef } from 'react';
|
|
3
|
+
import { ReactNode, memo, useRef } from 'react';
|
|
4
4
|
import { useTranslation } from 'react-i18next';
|
|
5
5
|
import { Flexbox } from 'react-layout-kit';
|
|
6
6
|
|
|
@@ -8,7 +8,6 @@ import SafeSpacing from '@/components/SafeSpacing';
|
|
|
8
8
|
import { usePluginStore } from '@/store/plugin';
|
|
9
9
|
|
|
10
10
|
import ChatList from './ChatList';
|
|
11
|
-
import ChatInput from './Input';
|
|
12
11
|
import ChatScrollAnchor from './ScrollAnchor';
|
|
13
12
|
|
|
14
13
|
const useStyles = createStyles(
|
|
@@ -23,7 +22,12 @@ const useStyles = createStyles(
|
|
|
23
22
|
`,
|
|
24
23
|
);
|
|
25
24
|
|
|
26
|
-
|
|
25
|
+
interface ConversationProps {
|
|
26
|
+
chatInput: ReactNode;
|
|
27
|
+
mobile?: boolean;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const Conversation = memo<ConversationProps>(({ mobile, chatInput }) => {
|
|
27
31
|
const ref = useRef(null);
|
|
28
32
|
const { t } = useTranslation('common');
|
|
29
33
|
const { styles } = useStyles();
|
|
@@ -41,7 +45,7 @@ const Conversation = memo<{ mobile?: boolean }>(({ mobile }) => {
|
|
|
41
45
|
</div>
|
|
42
46
|
<BackBottom target={ref} text={t('backToBottom')} />
|
|
43
47
|
</div>
|
|
44
|
-
|
|
48
|
+
{chatInput}
|
|
45
49
|
</Flexbox>
|
|
46
50
|
);
|
|
47
51
|
});
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import { memo } from 'react';
|
|
4
|
+
|
|
5
|
+
import PageTitle from '@/components/PageTitle';
|
|
6
|
+
import { useSessionStore } from '@/store/session';
|
|
7
|
+
import { agentSelectors } from '@/store/session/selectors';
|
|
8
|
+
import { genSiteHeadTitle } from '@/utils/genSiteHeadTitle';
|
|
9
|
+
|
|
10
|
+
const Title = memo(() => {
|
|
11
|
+
const [avatar, title] = useSessionStore((s) => [
|
|
12
|
+
agentSelectors.currentAgentAvatar(s),
|
|
13
|
+
agentSelectors.currentAgentTitle(s),
|
|
14
|
+
]);
|
|
15
|
+
const pageTitle = genSiteHeadTitle([avatar, title].filter(Boolean).join(' '));
|
|
16
|
+
|
|
17
|
+
return <PageTitle title={pageTitle} />;
|
|
18
|
+
});
|
|
19
|
+
export default Title;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { PropsWithChildren } from 'react';
|
|
2
|
+
|
|
3
|
+
import { isMobileDevice } from '@/utils/responsive';
|
|
4
|
+
|
|
5
|
+
import Desktop from './(desktop)/layout';
|
|
6
|
+
import Mobile from './(mobile)/layout';
|
|
7
|
+
|
|
8
|
+
const Layout = ({ children }: PropsWithChildren) => {
|
|
9
|
+
const mobile = isMobileDevice();
|
|
10
|
+
|
|
11
|
+
return mobile ? <Mobile>{children}</Mobile> : <Desktop>{children}</Desktop>;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
export default Layout;
|
package/src/app/chat/page.tsx
CHANGED
|
@@ -1,7 +1,12 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { isMobileDevice } from '@/utils/responsive';
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
import DesktopPage from './(desktop)';
|
|
4
|
+
import MobilePage from './(mobile)';
|
|
5
|
+
|
|
6
|
+
const Page = () => {
|
|
7
|
+
const mobile = isMobileDevice();
|
|
8
|
+
|
|
9
|
+
return mobile ? <MobilePage /> : <DesktopPage />;
|
|
5
10
|
};
|
|
6
11
|
|
|
7
|
-
export default
|
|
12
|
+
export default Page;
|
|
@@ -1,21 +1,22 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
1
3
|
import { PropsWithChildren, memo } from 'react';
|
|
2
4
|
import { Flexbox } from 'react-layout-kit';
|
|
3
5
|
|
|
4
6
|
import SafeSpacing from '@/components/SafeSpacing';
|
|
5
7
|
import { HEADER_HEIGHT } from '@/const/layoutTokens';
|
|
6
8
|
|
|
7
|
-
import
|
|
8
|
-
import Header from './features/Header';
|
|
9
|
+
import Header from './Header';
|
|
9
10
|
|
|
10
11
|
const DesktopLayout = memo<PropsWithChildren>(({ children }) => {
|
|
11
12
|
return (
|
|
12
|
-
|
|
13
|
+
<>
|
|
13
14
|
<Header />
|
|
14
15
|
<Flexbox align={'center'} flex={1} gap={16} padding={24} style={{ overflow: 'auto' }}>
|
|
15
16
|
<SafeSpacing height={HEADER_HEIGHT - 16} />
|
|
16
17
|
{children}
|
|
17
18
|
</Flexbox>
|
|
18
|
-
|
|
19
|
+
</>
|
|
19
20
|
);
|
|
20
21
|
});
|
|
21
22
|
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { memo } from 'react';
|
|
2
|
+
|
|
3
|
+
import { HeaderContent } from '@/app/chat/settings/components/Header';
|
|
4
|
+
import Layout from '@/app/chat/settings/components/Header/Mobile';
|
|
5
|
+
|
|
6
|
+
const Header = memo(() => (
|
|
7
|
+
<Layout>
|
|
8
|
+
<HeaderContent />
|
|
9
|
+
</Layout>
|
|
10
|
+
));
|
|
11
|
+
|
|
12
|
+
export default Header;
|
|
@@ -1,8 +1,10 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
1
3
|
import { PropsWithChildren, memo } from 'react';
|
|
2
4
|
|
|
3
5
|
import AppMobileLayout from '@/layout/AppMobileLayout';
|
|
4
6
|
|
|
5
|
-
import Header from './
|
|
7
|
+
import Header from './Header';
|
|
6
8
|
|
|
7
9
|
const MobileLayout = memo<PropsWithChildren>(({ children }) => {
|
|
8
10
|
return <AppMobileLayout navBar={<Header />}>{children}</AppMobileLayout>;
|
|
@@ -9,16 +9,11 @@ import { MOBILE_HEADER_ICON_SIZE } from '@/const/layoutTokens';
|
|
|
9
9
|
import { exportSingleAgent, exportSingleSession } from '@/helpers/export';
|
|
10
10
|
import { useSessionStore } from '@/store/session';
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
import Mobile from './Mobile';
|
|
14
|
-
|
|
15
|
-
const Header = memo<{ mobile?: boolean }>(() => {
|
|
12
|
+
export const HeaderContent = memo<{ mobile?: boolean }>(() => {
|
|
16
13
|
const { t } = useTranslation('setting');
|
|
17
14
|
const id = useSessionStore((s) => s.activeId);
|
|
18
15
|
const { mobile } = useResponsive();
|
|
19
16
|
|
|
20
|
-
const Render = mobile ? Mobile : Desktop;
|
|
21
|
-
|
|
22
17
|
const items = useMemo<MenuProps['items']>(
|
|
23
18
|
() => [
|
|
24
19
|
{
|
|
@@ -46,12 +41,8 @@ const Header = memo<{ mobile?: boolean }>(() => {
|
|
|
46
41
|
const size = mobile ? MOBILE_HEADER_ICON_SIZE : { fontSize: 24 };
|
|
47
42
|
|
|
48
43
|
return (
|
|
49
|
-
<
|
|
50
|
-
<
|
|
51
|
-
|
|
52
|
-
</Dropdown>
|
|
53
|
-
</Render>
|
|
44
|
+
<Dropdown arrow={false} menu={{ items }} trigger={['click']}>
|
|
45
|
+
<ActionIcon icon={HardDriveDownload} size={size} title={t('export', { ns: 'common' })} />
|
|
46
|
+
</Dropdown>
|
|
54
47
|
);
|
|
55
48
|
});
|
|
56
|
-
|
|
57
|
-
export default Header;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { PropsWithChildren } from 'react';
|
|
2
|
+
|
|
3
|
+
import { isMobileDevice } from '@/utils/responsive';
|
|
4
|
+
|
|
5
|
+
import Desktop from './(desktop)/layout.desktop';
|
|
6
|
+
import Mobile from './(mobile)/layout.mobile';
|
|
7
|
+
|
|
8
|
+
const Layout = ({ children }: PropsWithChildren) => {
|
|
9
|
+
const mobile = isMobileDevice();
|
|
10
|
+
|
|
11
|
+
return mobile ? <Mobile>{children}</Mobile> : <Desktop>{children}</Desktop>;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
export default Layout;
|
|
@@ -1,7 +1,38 @@
|
|
|
1
|
-
|
|
1
|
+
'use client';
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
};
|
|
3
|
+
import isEqual from 'fast-deep-equal';
|
|
4
|
+
import { memo } from 'react';
|
|
5
|
+
import { useTranslation } from 'react-i18next';
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
import PageTitle from '@/components/PageTitle';
|
|
8
|
+
import AgentSetting from '@/features/AgentSetting';
|
|
9
|
+
import { useSessionStore } from '@/store/session';
|
|
10
|
+
import { agentSelectors } from '@/store/session/selectors';
|
|
11
|
+
import { genSiteHeadTitle } from '@/utils/genSiteHeadTitle';
|
|
12
|
+
|
|
13
|
+
const EditPage = memo(() => {
|
|
14
|
+
const { t } = useTranslation('setting');
|
|
15
|
+
const config = useSessionStore(agentSelectors.currentAgentConfig, isEqual);
|
|
16
|
+
const meta = useSessionStore(agentSelectors.currentAgentMeta, isEqual);
|
|
17
|
+
const [updateAgentConfig, updateAgentMeta, title] = useSessionStore((s) => [
|
|
18
|
+
s.updateAgentConfig,
|
|
19
|
+
s.updateAgentMeta,
|
|
20
|
+
agentSelectors.currentAgentTitle(s),
|
|
21
|
+
]);
|
|
22
|
+
|
|
23
|
+
const pageTitle = genSiteHeadTitle(t('header.sessionWithName', { name: title }));
|
|
24
|
+
|
|
25
|
+
return (
|
|
26
|
+
<>
|
|
27
|
+
<PageTitle title={pageTitle} />
|
|
28
|
+
<AgentSetting
|
|
29
|
+
config={config}
|
|
30
|
+
meta={meta}
|
|
31
|
+
onConfigChange={updateAgentConfig}
|
|
32
|
+
onMetaChange={updateAgentMeta}
|
|
33
|
+
/>
|
|
34
|
+
</>
|
|
35
|
+
);
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
export default EditPage;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import { useRouter } from 'next/navigation';
|
|
4
|
+
import { memo, useEffect } from 'react';
|
|
5
|
+
|
|
6
|
+
import { useSessionStore } from '@/store/session';
|
|
7
|
+
import { sessionSelectors } from '@/store/session/selectors';
|
|
8
|
+
|
|
9
|
+
const Redirect = memo(() => {
|
|
10
|
+
const router = useRouter();
|
|
11
|
+
|
|
12
|
+
useEffect(() => {
|
|
13
|
+
useSessionStore.persist.onFinishHydration(() => {
|
|
14
|
+
const store = useSessionStore.getState();
|
|
15
|
+
const hasSession = sessionSelectors.hasSessionList(store);
|
|
16
|
+
|
|
17
|
+
if (hasSession) {
|
|
18
|
+
router.push('/chat');
|
|
19
|
+
store.switchSession();
|
|
20
|
+
} else {
|
|
21
|
+
router.push('/welcome');
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
}, []);
|
|
25
|
+
|
|
26
|
+
return null;
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
export default Redirect;
|
package/src/app/home/index.tsx
CHANGED
|
@@ -1,31 +1,20 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
import {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
useEffectAfterSessionHydrated(() => {
|
|
23
|
-
if (hasSession) switchSession();
|
|
24
|
-
}, [hasSession]);
|
|
25
|
-
|
|
26
|
-
if (!hydrated) return <Loading />;
|
|
27
|
-
|
|
28
|
-
return !hasSession ? <Welcome /> : <Loading />;
|
|
29
|
-
});
|
|
30
|
-
|
|
31
|
-
export default Home;
|
|
3
|
+
import { Icon, Logo } from '@lobehub/ui';
|
|
4
|
+
import { t } from 'i18next';
|
|
5
|
+
import { Loader2 } from 'lucide-react';
|
|
6
|
+
import { Center, Flexbox } from 'react-layout-kit';
|
|
7
|
+
|
|
8
|
+
const Loading = () => (
|
|
9
|
+
<Flexbox height={'100vh'} width={'100%'}>
|
|
10
|
+
<Center flex={1} gap={12} width={'100%'}>
|
|
11
|
+
<Logo extra={'Chat'} size={48} type={'combine'} />
|
|
12
|
+
<Center gap={16} horizontal>
|
|
13
|
+
<Icon icon={Loader2} spin />
|
|
14
|
+
{t('appInitializing', { ns: 'common' })}
|
|
15
|
+
</Center>
|
|
16
|
+
</Center>
|
|
17
|
+
</Flexbox>
|
|
18
|
+
);
|
|
19
|
+
|
|
20
|
+
export default Loading;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { createStyles } from 'antd-style';
|
|
2
|
-
import {
|
|
3
|
-
|
|
2
|
+
import { memo } from 'react';
|
|
3
|
+
|
|
4
|
+
import { useTokenCount } from '@/hooks/useTokenCount';
|
|
4
5
|
|
|
5
6
|
const useStyles = createStyles(
|
|
6
7
|
({ css, token }) => css`
|
|
@@ -17,7 +18,7 @@ const useStyles = createStyles(
|
|
|
17
18
|
|
|
18
19
|
const TokenTag = memo<{ systemRole: string }>(({ systemRole }) => {
|
|
19
20
|
const { styles } = useStyles();
|
|
20
|
-
const value =
|
|
21
|
+
const value = useTokenCount(systemRole);
|
|
21
22
|
|
|
22
23
|
return <div className={styles}>{value}</div>;
|
|
23
24
|
});
|
package/src/app/metadata.ts
CHANGED
|
@@ -46,7 +46,10 @@ const metadata: Metadata = {
|
|
|
46
46
|
{ color: '#f8f8f8', media: '(prefers-color-scheme: light)' },
|
|
47
47
|
{ color: '#000', media: '(prefers-color-scheme: dark)' },
|
|
48
48
|
],
|
|
49
|
-
title:
|
|
49
|
+
title: {
|
|
50
|
+
default: title,
|
|
51
|
+
template: '%s · LobeChat',
|
|
52
|
+
},
|
|
50
53
|
viewport: {
|
|
51
54
|
initialScale: 1,
|
|
52
55
|
maximumScale: 1,
|
package/src/app/page.tsx
CHANGED
|
@@ -3,10 +3,11 @@ import Link from 'next/link';
|
|
|
3
3
|
import { PropsWithChildren, memo } from 'react';
|
|
4
4
|
import { Center, Flexbox } from 'react-layout-kit';
|
|
5
5
|
|
|
6
|
-
import AppLayout from '
|
|
7
|
-
import { useStyles } from './features/Banner/style';
|
|
6
|
+
import AppLayout from '@/layout/AppLayout';
|
|
8
7
|
|
|
9
|
-
|
|
8
|
+
import { useStyles } from '../features/Banner/style';
|
|
9
|
+
|
|
10
|
+
const Desktop = memo<PropsWithChildren>(({ children }) => {
|
|
10
11
|
const { styles } = useStyles();
|
|
11
12
|
return (
|
|
12
13
|
<AppLayout>
|
|
@@ -28,4 +29,4 @@ const WelcomeLayout = memo<PropsWithChildren>(({ children }) => {
|
|
|
28
29
|
);
|
|
29
30
|
});
|
|
30
31
|
|
|
31
|
-
export default
|
|
32
|
+
export default Desktop;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import { useResponsive } from 'antd-style';
|
|
4
|
+
import { PropsWithChildren, memo } from 'react';
|
|
5
|
+
|
|
6
|
+
import Mobile from '../MobileLayout';
|
|
7
|
+
import Desktop from './Desktop';
|
|
8
|
+
|
|
9
|
+
const ResponsiveLayout = memo<PropsWithChildren>(({ children }) => {
|
|
10
|
+
const { mobile } = useResponsive();
|
|
11
|
+
|
|
12
|
+
return mobile ? <Mobile>{children}</Mobile> : <Desktop>{children}</Desktop>;
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
export default ResponsiveLayout;
|
|
@@ -1,11 +1,14 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
1
3
|
import { Logo, MobileNavBar } from '@lobehub/ui';
|
|
2
4
|
import { useTheme } from 'antd-style';
|
|
3
5
|
import { PropsWithChildren, memo } from 'react';
|
|
4
6
|
|
|
5
|
-
import AppMobileLayout from '
|
|
7
|
+
import AppMobileLayout from '@/layout/AppMobileLayout';
|
|
6
8
|
|
|
7
|
-
const
|
|
9
|
+
const MobileLayout = memo<PropsWithChildren>(({ children }) => {
|
|
8
10
|
const theme = useTheme();
|
|
11
|
+
|
|
9
12
|
return (
|
|
10
13
|
<AppMobileLayout
|
|
11
14
|
navBar={<MobileNavBar center={<Logo type={'text'} />} />}
|
|
@@ -17,4 +20,4 @@ const WelcomeLayout = memo<PropsWithChildren>(({ children }) => {
|
|
|
17
20
|
);
|
|
18
21
|
});
|
|
19
22
|
|
|
20
|
-
export default
|
|
23
|
+
export default MobileLayout;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { PropsWithChildren } from 'react';
|
|
2
|
+
|
|
3
|
+
import { isMobileDevice } from '@/utils/responsive';
|
|
4
|
+
|
|
5
|
+
import Desktop from './DesktopLayout';
|
|
6
|
+
import Mobile from './MobileLayout';
|
|
7
|
+
import Footer from './features/Footer';
|
|
8
|
+
|
|
9
|
+
const Layout = ({ children }: PropsWithChildren) => {
|
|
10
|
+
const mobile = isMobileDevice();
|
|
11
|
+
|
|
12
|
+
return mobile ? (
|
|
13
|
+
<Mobile>{children}</Mobile>
|
|
14
|
+
) : (
|
|
15
|
+
<Desktop>
|
|
16
|
+
{children}
|
|
17
|
+
<Footer />
|
|
18
|
+
</Desktop>
|
|
19
|
+
);
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
export default Layout;
|
package/src/app/welcome/page.tsx
CHANGED
|
@@ -1,7 +1,12 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { t } from 'i18next';
|
|
2
|
+
import { Metadata } from 'next';
|
|
2
3
|
|
|
3
|
-
|
|
4
|
-
return <Page />;
|
|
5
|
-
};
|
|
4
|
+
import Banner from './features/Banner';
|
|
6
5
|
|
|
7
|
-
export
|
|
6
|
+
export const generateMetadata = (): Metadata => ({
|
|
7
|
+
title: t('header', { ns: 'welcome' }),
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
const Page = () => <Banner />;
|
|
11
|
+
|
|
12
|
+
export default Page;
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { EditableMessage, FormGroup, TokenTag } from '@lobehub/ui';
|
|
2
2
|
import { Button } from 'antd';
|
|
3
3
|
import { createStyles } from 'antd-style';
|
|
4
|
-
import { encode } from 'gpt-tokenizer';
|
|
5
4
|
import { Bot } from 'lucide-react';
|
|
6
5
|
import { memo, useState } from 'react';
|
|
7
6
|
import { useTranslation } from 'react-i18next';
|
|
@@ -9,6 +8,7 @@ import { Flexbox } from 'react-layout-kit';
|
|
|
9
8
|
|
|
10
9
|
import { FORM_STYLE } from '@/const/layoutTokens';
|
|
11
10
|
import { ModelTokens } from '@/const/modelTokens';
|
|
11
|
+
import { useTokenCount } from '@/hooks/useTokenCount';
|
|
12
12
|
|
|
13
13
|
import { useStore } from '../store';
|
|
14
14
|
|
|
@@ -26,11 +26,8 @@ const AgentPrompt = memo(() => {
|
|
|
26
26
|
const { styles } = useStyles();
|
|
27
27
|
const [editing, setEditing] = useState(false);
|
|
28
28
|
const updateConfig = useStore((s) => s.setAgentConfig);
|
|
29
|
-
const [systemRole, model
|
|
30
|
-
|
|
31
|
-
s.config.model,
|
|
32
|
-
encode(s.config.systemRole || '').length,
|
|
33
|
-
]);
|
|
29
|
+
const [systemRole, model] = useStore((s) => [s.config.systemRole, s.config.model]);
|
|
30
|
+
const systemTokenCount = useTokenCount(systemRole);
|
|
34
31
|
|
|
35
32
|
return (
|
|
36
33
|
<FormGroup
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { startTransition, useEffect, useState } from 'react';
|
|
2
|
+
|
|
3
|
+
import { encodeAsync } from '@/utils/tokenizer';
|
|
4
|
+
|
|
5
|
+
export const useTokenCount = (input: string = '') => {
|
|
6
|
+
const [value, setNum] = useState(0);
|
|
7
|
+
|
|
8
|
+
useEffect(() => {
|
|
9
|
+
startTransition(() => {
|
|
10
|
+
encodeAsync(input)
|
|
11
|
+
.then(setNum)
|
|
12
|
+
.catch(() => {
|
|
13
|
+
// 兜底采用字符数
|
|
14
|
+
setNum(input.length);
|
|
15
|
+
});
|
|
16
|
+
});
|
|
17
|
+
}, [input]);
|
|
18
|
+
|
|
19
|
+
return value;
|
|
20
|
+
};
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { type MobileNavBarTitleProps } from '@lobehub/ui';
|
|
2
2
|
import { createStyles } from 'antd-style';
|
|
3
|
-
import Head from 'next/head';
|
|
4
3
|
import { CSSProperties, PropsWithChildren, ReactNode, memo } from 'react';
|
|
5
4
|
import { Flexbox } from 'react-layout-kit';
|
|
6
5
|
|
|
@@ -49,29 +48,21 @@ const AppMobileLayout = memo<AppMobileLayoutProps>(
|
|
|
49
48
|
const { styles, cx } = useStyles();
|
|
50
49
|
|
|
51
50
|
return (
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
{showTabBar && (
|
|
68
|
-
<>
|
|
69
|
-
<SafeSpacing mobile position={'bottom'} />
|
|
70
|
-
<MobileTabBar className={styles.mobileTabBar} />
|
|
71
|
-
</>
|
|
72
|
-
)}
|
|
73
|
-
</Flexbox>
|
|
74
|
-
</>
|
|
51
|
+
<Flexbox className={cx(styles.container, className)} style={style}>
|
|
52
|
+
{navBar && (
|
|
53
|
+
<>
|
|
54
|
+
<div className={styles.mobileNavBar}>{navBar}</div>
|
|
55
|
+
<SafeSpacing mobile position={'top'} />
|
|
56
|
+
</>
|
|
57
|
+
)}
|
|
58
|
+
{children}
|
|
59
|
+
{showTabBar && (
|
|
60
|
+
<>
|
|
61
|
+
<SafeSpacing mobile position={'bottom'} />
|
|
62
|
+
<MobileTabBar className={styles.mobileTabBar} />
|
|
63
|
+
</>
|
|
64
|
+
)}
|
|
65
|
+
</Flexbox>
|
|
75
66
|
);
|
|
76
67
|
},
|
|
77
68
|
);
|
package/src/prompts/chat.ts
CHANGED
|
@@ -2,7 +2,9 @@ import { chatHelpers } from '@/store/session/helpers';
|
|
|
2
2
|
import { LanguageModel } from '@/types/llm';
|
|
3
3
|
import { OpenAIChatMessage, OpenAIStreamPayload } from '@/types/openai';
|
|
4
4
|
|
|
5
|
-
export const promptSummaryTitle = (
|
|
5
|
+
export const promptSummaryTitle = async (
|
|
6
|
+
messages: OpenAIChatMessage[],
|
|
7
|
+
): Promise<Partial<OpenAIStreamPayload>> => {
|
|
6
8
|
const finalMessages: OpenAIChatMessage[] = [
|
|
7
9
|
{
|
|
8
10
|
content:
|
|
@@ -17,7 +19,7 @@ export const promptSummaryTitle = (messages: OpenAIChatMessage[]): Partial<OpenA
|
|
|
17
19
|
},
|
|
18
20
|
];
|
|
19
21
|
// 如果超过 4k,则使用 GPT3.5 16K 模型
|
|
20
|
-
const tokens = chatHelpers.getMessagesTokenCount(finalMessages);
|
|
22
|
+
const tokens = await chatHelpers.getMessagesTokenCount(finalMessages);
|
|
21
23
|
let model: LanguageModel | undefined = undefined;
|
|
22
24
|
if (tokens > 4000) {
|
|
23
25
|
model = LanguageModel.GPT3_5_16K;
|