@lobehub/chat 0.43.0 → 0.44.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 (72) hide show
  1. package/.github/workflows/release.yml +1 -1
  2. package/CHANGELOG.md +49 -0
  3. package/package.json +5 -2
  4. package/src/const/meta.ts +3 -0
  5. package/src/const/session.ts +1 -0
  6. package/src/helpers/export.ts +15 -9
  7. package/src/locales/default/common.ts +8 -1
  8. package/src/pages/chat/SessionList/Inbox.tsx +23 -0
  9. package/src/pages/chat/SessionList/List/SessionItem.tsx +15 -4
  10. package/src/pages/chat/SessionList/List/index.tsx +3 -2
  11. package/src/pages/chat/SessionList/index.tsx +13 -1
  12. package/src/pages/chat/[id]/index.page.tsx +7 -9
  13. package/src/pages/chat/[id]/layout.tsx +7 -23
  14. package/src/pages/chat/[id]/setting/index.page.tsx +3 -3
  15. package/src/pages/chat/features/Conversation/ChatList/SkeletonList.tsx +43 -0
  16. package/src/pages/chat/{[id] → features}/Conversation/ChatList/index.tsx +35 -5
  17. package/src/pages/chat/{[id] → features}/Conversation/Input/index.tsx +1 -1
  18. package/src/pages/chat/{[id] → features}/Header/index.tsx +32 -34
  19. package/src/pages/chat/features/Sidebar/Inner.tsx +42 -0
  20. package/src/pages/chat/{[id]/Sidebar/Inner.tsx → features/Sidebar/SystemRole.tsx} +7 -37
  21. package/src/pages/chat/{[id] → features}/Sidebar/index.tsx +8 -4
  22. package/src/pages/chat/index.page.tsx +39 -1
  23. package/src/pages/chat/layout.tsx +27 -0
  24. package/src/pages/welcome/Footer/index.tsx +1 -0
  25. package/src/services/chatModel.ts +1 -1
  26. package/src/store/global/hooks/useOnFinishHydrationGlobal.ts +18 -0
  27. package/src/store/global/hooks/useSwitchSideBarOnInit.ts +4 -8
  28. package/src/store/session/hooks/index.ts +2 -0
  29. package/src/store/session/hooks/useOnFinishHydrationSession.ts +18 -0
  30. package/src/store/session/hooks/useSessionHydrated.ts +1 -1
  31. package/src/store/session/index.ts +1 -3
  32. package/src/store/session/initialState.ts +6 -3
  33. package/src/store/session/selectors.ts +3 -3
  34. package/src/store/session/slices/agentConfig/action.ts +2 -1
  35. package/src/store/session/slices/agentConfig/selectors.ts +11 -11
  36. package/src/store/session/slices/chat/actions/message.ts +13 -20
  37. package/src/store/session/slices/chat/actions/topic.ts +3 -1
  38. package/src/store/session/slices/chat/selectors/chat.ts +1 -1
  39. package/src/store/session/slices/chat/selectors/token.ts +1 -1
  40. package/src/store/session/slices/chat/selectors/topic.ts +4 -2
  41. package/src/store/session/slices/session/action.ts +29 -15
  42. package/src/store/session/slices/session/initialState.ts +18 -4
  43. package/src/store/session/slices/session/selectors/export.ts +13 -8
  44. package/src/store/session/slices/session/selectors/list.test.ts +303 -0
  45. package/src/store/session/slices/session/selectors/list.ts +8 -3
  46. package/src/store/session/store.ts +5 -5
  47. package/src/types/exportConfig.ts +93 -31
  48. package/src/utils/config.ts +9 -0
  49. package/src/pages/chat/SessionList/List/style.ts +0 -36
  50. package/src/store/session/slices/chat/index.ts +0 -3
  51. package/src/store/session/slices/session/index.ts +0 -3
  52. package/src/pages/chat/{[id] → features}/Conversation/ChatList/Error/ApiKeyForm.tsx +0 -0
  53. package/src/pages/chat/{[id] → features}/Conversation/ChatList/Error/ErrorActionContainer.tsx +0 -0
  54. package/src/pages/chat/{[id] → features}/Conversation/ChatList/Error/InvalidAccess.tsx +1 -1
  55. /package/src/pages/chat/{[id] → features}/Conversation/ChatList/Error/OpenAiBizError.tsx +0 -0
  56. /package/src/pages/chat/{[id] → features}/Conversation/ChatList/Error/style.tsx +0 -0
  57. /package/src/pages/chat/{[id] → features}/Conversation/ChatList/MessageExtra.tsx +0 -0
  58. /package/src/pages/chat/{[id] → features}/Conversation/ChatList/OTPInput.tsx +0 -0
  59. /package/src/pages/chat/{[id] → features}/Conversation/ChatList/Plugins/FunctionCall.tsx +0 -0
  60. /package/src/pages/chat/{[id] → features}/Conversation/ChatList/Plugins/PluginMessage.tsx +0 -0
  61. /package/src/pages/chat/{[id] → features}/Conversation/ChatList/Plugins/PluginResultRender.tsx +0 -0
  62. /package/src/pages/chat/{[id] → features}/Conversation/ChatList/Plugins/style.ts +0 -0
  63. /package/src/pages/chat/{[id] → features}/Conversation/Input/Action.tsx +0 -0
  64. /package/src/pages/chat/{[id] → features}/Conversation/Input/ActionRight.tsx +0 -0
  65. /package/src/pages/chat/{[id] → features}/Conversation/Input/Token.tsx +0 -0
  66. /package/src/pages/chat/{[id] → features}/Conversation/index.tsx +0 -0
  67. /package/src/pages/chat/{[id] → features}/Header/PluginTag.tsx +0 -0
  68. /package/src/pages/chat/{[id] → features}/Sidebar/Header.tsx +0 -0
  69. /package/src/pages/chat/{[id] → features}/Sidebar/Topic/DefaultContent.tsx +0 -0
  70. /package/src/pages/chat/{[id] → features}/Sidebar/Topic/TopicContent.tsx +0 -0
  71. /package/src/pages/chat/{[id] → features}/Sidebar/Topic/TopicItem.tsx +0 -0
  72. /package/src/pages/chat/{[id] → features}/Sidebar/Topic/index.tsx +0 -0
@@ -9,30 +9,37 @@ import { Flexbox } from 'react-layout-kit';
9
9
 
10
10
  import HeaderTitle from '@/components/HeaderTitle';
11
11
  import Tag from '@/components/Tag';
12
+ import { INBOX_SESSION_ID } from '@/const/session';
12
13
  import { useGlobalStore } from '@/store/global';
13
14
  import { agentSelectors, useSessionHydrated, useSessionStore } from '@/store/session';
14
15
 
15
16
  import PluginTag from './PluginTag';
16
17
 
17
- const Header = memo(() => {
18
+ const Header = memo<{ settings?: boolean }>(({ settings = true }) => {
18
19
  const init = useSessionHydrated();
20
+
19
21
  const { t } = useTranslation('common');
20
22
 
21
- const [title, description, avatar, backgroundColor, id, model, plugins] = useSessionStore((s) => [
23
+ const [id, title, description, avatar, backgroundColor, model, plugins] = useSessionStore((s) => [
24
+ s.activeId,
25
+
22
26
  agentSelectors.currentAgentTitle(s),
23
27
  agentSelectors.currentAgentDescription(s),
24
28
  agentSelectors.currentAgentAvatar(s),
25
29
  agentSelectors.currentAgentBackgroundColor(s),
26
- s.activeId,
27
30
  agentSelectors.currentAgentModel(s),
28
31
  agentSelectors.currentAgentPlugins(s),
29
32
  ]);
30
33
 
34
+ const isInbox = id === INBOX_SESSION_ID;
31
35
  const [showAgentSettings, toggleConfig] = useGlobalStore((s) => [
32
36
  s.preference.showChatSideBar,
33
37
  s.toggleChatSideBar,
34
38
  ]);
35
39
 
40
+ const displayTitle = isInbox ? t('inbox.title') : title;
41
+ const displayDesc = isInbox ? t('inbox.desc') : description;
42
+
36
43
  return (
37
44
  <ChatHeader
38
45
  left={
@@ -48,49 +55,40 @@ const Header = memo(() => {
48
55
  </Flexbox>
49
56
  ) : (
50
57
  <Flexbox align={'flex-start'} gap={12} horizontal>
51
- <Avatar
52
- avatar={avatar}
53
- background={backgroundColor}
54
- onClick={() => {
55
- Router.push(`/chat/${id}/setting`);
56
- }}
57
- size={40}
58
- style={{ cursor: 'pointer', flex: 'none' }}
59
- title={title}
60
- />
58
+ <Avatar avatar={avatar} background={backgroundColor} size={40} title={title} />
61
59
  <HeaderTitle
62
- desc={description}
60
+ desc={displayDesc}
63
61
  tag={
64
62
  <>
65
63
  <Tag>
66
- <SiOpenai size={'11px'} style={{ marginTop: 3 }} />
64
+ <SiOpenai size={'11px'} style={{ marginTop: 2 }} />
67
65
  {model}
68
66
  </Tag>
69
67
  {plugins?.length > 0 && <PluginTag plugins={plugins} />}
70
68
  </>
71
69
  }
72
- title={title}
70
+ title={displayTitle}
73
71
  />
74
72
  </Flexbox>
75
73
  )
76
74
  }
77
75
  right={
78
- id && (
79
- <>
80
- {/*<ActionIcon*/}
81
- {/* icon={Share2}*/}
82
- {/* onClick={() => {*/}
83
- {/* // genShareUrl();*/}
84
- {/* }}*/}
85
- {/* size={{ fontSize: 24 }}*/}
86
- {/* title={t('share')}*/}
87
- {/*/>*/}
88
- <ActionIcon
89
- icon={showAgentSettings ? PanelRightClose : PanelRightOpen}
90
- onClick={() => toggleConfig()}
91
- size={{ fontSize: 24 }}
92
- title={t('roleAndArchive')}
93
- />
76
+ <>
77
+ {/*<ActionIcon*/}
78
+ {/* icon={Share2}*/}
79
+ {/* onClick={() => {*/}
80
+ {/* // genShareUrl();*/}
81
+ {/* }}*/}
82
+ {/* size={{ fontSize: 24 }}*/}
83
+ {/* title={t('share')}*/}
84
+ {/*/>*/}
85
+ <ActionIcon
86
+ icon={showAgentSettings ? PanelRightClose : PanelRightOpen}
87
+ onClick={() => toggleConfig()}
88
+ size={{ fontSize: 24 }}
89
+ title={t('roleAndArchive')}
90
+ />
91
+ {settings && (
94
92
  <ActionIcon
95
93
  icon={Settings}
96
94
  onClick={() => {
@@ -99,8 +97,8 @@ const Header = memo(() => {
99
97
  size={{ fontSize: 24 }}
100
98
  title={t('header.session', { ns: 'setting' })}
101
99
  />
102
- </>
103
- )
100
+ )}
101
+ </>
104
102
  }
105
103
  />
106
104
  );
@@ -0,0 +1,42 @@
1
+ import { DraggablePanelBody, SearchBar } from '@lobehub/ui';
2
+ import { Skeleton } from 'antd';
3
+ import { memo } from 'react';
4
+ import { useTranslation } from 'react-i18next';
5
+ import { Flexbox } from 'react-layout-kit';
6
+
7
+ import { useSessionHydrated } from '@/store/session';
8
+
9
+ import SystemRole from './SystemRole';
10
+ import { Topic } from './Topic';
11
+
12
+ const Inner = memo<{ systemRole: boolean }>(({ systemRole }) => {
13
+ const hydrated = useSessionHydrated();
14
+ const { t } = useTranslation('common');
15
+
16
+ return (
17
+ <DraggablePanelBody style={{ padding: 0 }}>
18
+ {systemRole && <SystemRole />}
19
+ <Flexbox gap={16} padding={16}>
20
+ <SearchBar placeholder={t('topic.searchPlaceholder')} spotlight type={'ghost'} />
21
+ {!hydrated ? (
22
+ <Flexbox gap={8} style={{ marginTop: 8 }}>
23
+ {Array.from({ length: 8 }).map((_, i) => (
24
+ <Skeleton
25
+ active
26
+ avatar={false}
27
+ key={i}
28
+ paragraph={{ rows: 1, width: '100%' }}
29
+ round
30
+ title={false}
31
+ />
32
+ ))}
33
+ </Flexbox>
34
+ ) : (
35
+ <Topic />
36
+ )}
37
+ </Flexbox>
38
+ </DraggablePanelBody>
39
+ );
40
+ });
41
+
42
+ export default Inner;
@@ -1,4 +1,4 @@
1
- import { ActionIcon, DraggablePanelBody, EditableMessage, SearchBar } from '@lobehub/ui';
1
+ import { ActionIcon, EditableMessage } from '@lobehub/ui';
2
2
  import { Skeleton } from 'antd';
3
3
  import { createStyles } from 'antd-style';
4
4
  import { Maximize2Icon } from 'lucide-react';
@@ -6,18 +6,10 @@ import { memo, useState } from 'react';
6
6
  import { useTranslation } from 'react-i18next';
7
7
  import { Flexbox } from 'react-layout-kit';
8
8
 
9
+ import Header from '@/pages/chat/features/Sidebar/Header';
9
10
  import { agentSelectors, useSessionHydrated, useSessionStore } from '@/store/session';
10
11
 
11
- import Header from './Header';
12
- import { Topic } from './Topic';
13
-
14
12
  const useStyles = createStyles(({ css, token }) => ({
15
- desc: css`
16
- color: ${token.colorText};
17
- `,
18
- model: css`
19
- color: ${token.colorTextTertiary};
20
- `,
21
13
  prompt: css`
22
14
  overflow-x: hidden;
23
15
  overflow-y: auto;
@@ -46,14 +38,11 @@ const useStyles = createStyles(({ css, token }) => ({
46
38
 
47
39
  background: linear-gradient(to bottom, transparent, ${token.colorBgLayout});
48
40
  `,
49
- title: css`
50
- font-size: ${token.fontSizeHeading4}px;
51
- font-weight: bold;
52
- `,
53
41
  }));
54
42
 
55
- const Inner = memo(() => {
43
+ const SystemRole = memo(() => {
56
44
  const [openModal, setOpenModal] = useState(false);
45
+
57
46
  const { styles } = useStyles();
58
47
  const [systemRole, updateAgentConfig] = useSessionStore((s) => [
59
48
  agentSelectors.currentAgentSystemRole(s),
@@ -63,7 +52,7 @@ const Inner = memo(() => {
63
52
  const hydrated = useSessionHydrated();
64
53
  const { t } = useTranslation('common');
65
54
  return (
66
- <DraggablePanelBody style={{ padding: 0 }}>
55
+ <>
67
56
  <Header
68
57
  actions={
69
58
  <ActionIcon
@@ -101,27 +90,8 @@ const Inner = memo(() => {
101
90
  <Skeleton active avatar={false} style={{ marginTop: 12 }} title={false} />
102
91
  )}
103
92
  </Flexbox>
104
- <Flexbox gap={16} padding={16}>
105
- <SearchBar placeholder={t('topic.searchPlaceholder')} spotlight type={'ghost'} />
106
- {!hydrated ? (
107
- <Flexbox gap={8} style={{ marginTop: 8 }}>
108
- {Array.from({ length: 8 }).map((_, i) => (
109
- <Skeleton
110
- active
111
- avatar={false}
112
- key={i}
113
- paragraph={{ rows: 1, width: '100%' }}
114
- round
115
- title={false}
116
- />
117
- ))}
118
- </Flexbox>
119
- ) : (
120
- <Topic />
121
- )}
122
- </Flexbox>
123
- </DraggablePanelBody>
93
+ </>
124
94
  );
125
95
  });
126
96
 
127
- export default Inner;
97
+ export default SystemRole;
@@ -1,6 +1,7 @@
1
1
  import { DraggablePanel, DraggablePanelContainer } from '@lobehub/ui';
2
2
  import { createStyles } from 'antd-style';
3
3
  import { rgba } from 'polished';
4
+ import { memo } from 'react';
4
5
 
5
6
  import HeaderSpacing from '@/components/HeaderSpacing';
6
7
  import { CHAT_SIDEBAR_WIDTH } from '@/const/layoutTokens';
@@ -20,7 +21,10 @@ const useStyles = createStyles(({ cx, css, token, stylish }) => ({
20
21
  `,
21
22
  }));
22
23
 
23
- const Config = () => {
24
+ interface SideBarProps {
25
+ systemRole?: boolean;
26
+ }
27
+ const SideBar = memo<SideBarProps>(({ systemRole = true }) => {
24
28
  const { styles } = useStyles();
25
29
  const [showAgentSettings, toggleConfig] = useGlobalStore((s) => [
26
30
  s.preference.showChatSideBar,
@@ -37,10 +41,10 @@ const Config = () => {
37
41
  >
38
42
  <HeaderSpacing />
39
43
  <DraggablePanelContainer style={{ flex: 'none', minWidth: CHAT_SIDEBAR_WIDTH }}>
40
- <Inner />
44
+ <Inner systemRole={systemRole} />
41
45
  </DraggablePanelContainer>
42
46
  </DraggablePanel>
43
47
  );
44
- };
48
+ });
45
49
 
46
- export default Config;
50
+ export default SideBar;
@@ -1 +1,39 @@
1
- export { default } from './[id]/index.page';
1
+ import Head from 'next/head';
2
+ import { memo } from 'react';
3
+ import { useTranslation } from 'react-i18next';
4
+ import { Flexbox } from 'react-layout-kit';
5
+
6
+ import { INBOX_SESSION_ID } from '@/const/session';
7
+ import { useOnFinishHydrationSession, useSessionStore } from '@/store/session';
8
+ import { genSiteHeadTitle } from '@/utils/genSiteHeadTitle';
9
+
10
+ import Conversation from './features/Conversation';
11
+ import Header from './features/Header';
12
+ import SideBar from './features/Sidebar';
13
+ import Layout from './layout';
14
+
15
+ const Chat = memo(() => {
16
+ const { t } = useTranslation('common');
17
+
18
+ const pageTitle = genSiteHeadTitle(t('inbox.title'));
19
+
20
+ useOnFinishHydrationSession(() => {
21
+ useSessionStore.getState().activeSession(INBOX_SESSION_ID);
22
+ });
23
+
24
+ return (
25
+ <>
26
+ <Head>
27
+ <title>{pageTitle}</title>
28
+ </Head>
29
+ <Layout>
30
+ <Header settings={false} />
31
+ <Flexbox flex={1} height={'calc(100vh - 64px)'} horizontal>
32
+ <Conversation />
33
+ <SideBar systemRole={false} />
34
+ </Flexbox>
35
+ </Layout>
36
+ </>
37
+ );
38
+ });
39
+ export default Chat;
@@ -0,0 +1,27 @@
1
+ import { PropsWithChildren, memo } from 'react';
2
+ import { Flexbox } from 'react-layout-kit';
3
+
4
+ import AppLayout from '@/layout/AppLayout';
5
+ import { useSwitchSideBarOnInit } from '@/store/global';
6
+
7
+ import { Sessions } from './SessionList';
8
+
9
+ const ChatLayout = memo<PropsWithChildren>(({ children }) => {
10
+ useSwitchSideBarOnInit('chat');
11
+
12
+ return (
13
+ <AppLayout>
14
+ <Sessions />
15
+ <Flexbox
16
+ flex={1}
17
+ height={'100vh'}
18
+ id={'lobe-conversion-container'}
19
+ style={{ position: 'relative' }}
20
+ >
21
+ {children}
22
+ </Flexbox>
23
+ </AppLayout>
24
+ );
25
+ });
26
+
27
+ export default ChatLayout;
@@ -9,6 +9,7 @@ import { CHANGELOG, DISCORD, GITHUB } from '@/const/url';
9
9
 
10
10
  const Footer = memo(() => {
11
11
  const theme = useTheme();
12
+
12
13
  return (
13
14
  <Flexbox align={'center'} horizontal justify={'space-between'} style={{ padding: 16 }}>
14
15
  <span style={{ color: theme.colorTextDescription }}>©{new Date().getFullYear()} LobeHub</span>
@@ -2,7 +2,7 @@ import { merge } from 'lodash-es';
2
2
 
3
3
  import { LOBE_CHAT_ACCESS_CODE, OPENAI_API_KEY_HEADER_KEY, OPENAI_END_POINT } from '@/const/fetch';
4
4
  import { useGlobalStore } from '@/store/global';
5
- import { initialLobeAgentConfig } from '@/store/session';
5
+ import { initialLobeAgentConfig } from '@/store/session/initialState';
6
6
  import type { OpenAIStreamPayload } from '@/types/openai';
7
7
 
8
8
  import { URLS } from './url';
@@ -0,0 +1,18 @@
1
+ import { useEffect } from 'react';
2
+
3
+ import { useGlobalStore } from '../store';
4
+
5
+ /**
6
+ * 当 Session 水合完毕后才会执行的 useEffect
7
+ * @param fn
8
+ * @param deps
9
+ */
10
+ export const useOnFinishHydrationGlobal = (fn: () => void, deps: any[] = []) => {
11
+ useEffect(() => {
12
+ const hasRehydrated = useGlobalStore.persist.hasHydrated();
13
+ // 只有当水合完毕后再开始做操作
14
+ if (!hasRehydrated) return;
15
+
16
+ fn();
17
+ }, deps);
18
+ };
@@ -1,17 +1,13 @@
1
- import { useEffect } from 'react';
2
-
3
1
  import { SidebarTabKey } from '../initialState';
4
2
  import { useGlobalStore } from '../store';
3
+ import { useOnFinishHydrationGlobal } from './useOnFinishHydrationGlobal';
5
4
 
6
5
  /**
7
6
  * 切换侧边栏选项
8
7
  * @desc 只会在应用初始化时(且水合后)执行一次
9
8
  */
10
9
  export const useSwitchSideBarOnInit = (key: SidebarTabKey) => {
11
- useEffect(() => {
12
- const hasRehydrated = useGlobalStore.persist.hasHydrated();
13
- if (hasRehydrated) {
14
- useGlobalStore.getState().switchSideBar(key);
15
- }
16
- }, []);
10
+ useOnFinishHydrationGlobal(() => {
11
+ useGlobalStore.getState().switchSideBar(key);
12
+ });
17
13
  };
@@ -0,0 +1,2 @@
1
+ export * from './useOnFinishHydrationSession';
2
+ export * from './useSessionHydrated';
@@ -0,0 +1,18 @@
1
+ import { useEffect } from 'react';
2
+
3
+ import { useSessionStore } from '../store';
4
+
5
+ /**
6
+ * 当 Session 水合完毕后才会执行的 useEffect
7
+ * @param fn
8
+ * @param deps
9
+ */
10
+ export const useOnFinishHydrationSession = (fn: () => void, deps: any[] = []) => {
11
+ useEffect(() => {
12
+ const hasRehydrated = useSessionStore.persist.hasHydrated();
13
+ // 只有当水合完毕后再开始做操作
14
+ if (!hasRehydrated) return;
15
+
16
+ fn();
17
+ }, deps);
18
+ };
@@ -1,6 +1,6 @@
1
1
  import { useEffect, useState } from 'react';
2
2
 
3
- import { useSessionStore } from '@/store/session';
3
+ import { useSessionStore } from '../store';
4
4
 
5
5
  export const useSessionHydrated = () => {
6
6
  // 根据 sessions 是否有值来判断是否已经初始化
@@ -1,6 +1,4 @@
1
- export * from './hooks/useSessionHydrated';
1
+ export * from './hooks';
2
2
  export * from './selectors';
3
- export { initialLobeAgentConfig } from './slices/agentConfig';
4
- export { initLobeSession } from './slices/session';
5
3
  export type { SessionStore } from './store';
6
4
  export { useSessionStore } from './store';
@@ -1,6 +1,6 @@
1
- import { AgentConfigState, initialAgentConfigState } from './slices/agentConfig';
2
- import { ChatState, initialChatState } from './slices/chat';
3
- import { SessionState, initialSessionState } from './slices/session';
1
+ import { AgentConfigState, initialAgentConfigState } from './slices/agentConfig/initialState';
2
+ import { ChatState, initialChatState } from './slices/chat/initialState';
3
+ import { SessionState, initialSessionState } from './slices/session/initialState';
4
4
 
5
5
  export type SessionStoreState = SessionState & ChatState & AgentConfigState;
6
6
 
@@ -9,3 +9,6 @@ export const initialState: SessionStoreState = {
9
9
  ...initialChatState,
10
10
  ...initialAgentConfigState,
11
11
  };
12
+
13
+ export { initialLobeAgentConfig } from './slices/agentConfig';
14
+ export { initLobeSession } from './slices/session/initialState';
@@ -1,3 +1,3 @@
1
- export { agentSelectors } from './slices/agentConfig';
2
- export { chatSelectors, topicSelectors } from './slices/chat';
3
- export { sessionSelectors } from './slices/session';
1
+ export { agentSelectors } from './slices/agentConfig/selectors';
2
+ export { chatSelectors, topicSelectors } from './slices/chat/selectors';
3
+ export { sessionSelectors } from './slices/session/selectors';
@@ -2,12 +2,13 @@ import { produce } from 'immer';
2
2
  import { StateCreator } from 'zustand/vanilla';
3
3
 
4
4
  import { promptPickEmoji, promptSummaryAgentName, promptSummaryDescription } from '@/prompts/agent';
5
- import { SessionStore, sessionSelectors } from '@/store/session';
6
5
  import { MetaData } from '@/types/meta';
7
6
  import { LobeAgentConfig } from '@/types/session';
8
7
  import { fetchPresetTaskResult } from '@/utils/fetch';
9
8
  import { setNamespace } from '@/utils/storeDebug';
10
9
 
10
+ import { SessionStore } from '../../store';
11
+ import { sessionSelectors } from '../session/selectors';
11
12
  import { SessionLoadingState } from './initialState';
12
13
 
13
14
  const t = setNamespace('agentConfig');
@@ -7,7 +7,7 @@ import { SessionStore } from '@/store/session';
7
7
  import { LanguageModel } from '@/types/llm';
8
8
  import { MetaData } from '@/types/meta';
9
9
 
10
- import { sessionSelectors } from '../session';
10
+ import { sessionSelectors } from '../session/selectors';
11
11
  import { initialLobeAgentConfig } from './initialState';
12
12
 
13
13
  const currentAgentMeta = (s: SessionStore): MetaData => {
@@ -25,8 +25,17 @@ const currentAutocomplete = (s: SessionStore): Autocomplete => ({
25
25
 
26
26
  const currentAgentTitle = (s: SessionStore) => currentAgentMeta(s)?.title || t('defaultSession');
27
27
 
28
+ const currentAgentConfig = (s: SessionStore) => {
29
+ const session = sessionSelectors.currentSession(s);
30
+ return merge({}, initialLobeAgentConfig, session?.config);
31
+ };
32
+
33
+ const currentAgentSystemRole = (s: SessionStore) => {
34
+ return currentAgentConfig(s).systemRole;
35
+ };
36
+
28
37
  const currentAgentDescription = (s: SessionStore) =>
29
- currentAgentMeta(s)?.description || t('noDescription');
38
+ currentAgentMeta(s)?.description || currentAgentSystemRole(s) || t('noDescription');
30
39
 
31
40
  const currentAgentBackgroundColor = (s: SessionStore) => {
32
41
  const session = sessionSelectors.currentSession(s);
@@ -41,15 +50,6 @@ const currentAgentAvatar = (s: SessionStore) => {
41
50
  return session.meta.avatar || DEFAULT_AVATAR;
42
51
  };
43
52
 
44
- const currentAgentConfig = (s: SessionStore) => {
45
- const session = sessionSelectors.currentSession(s);
46
- return merge({}, initialLobeAgentConfig, session?.config);
47
- };
48
-
49
- const currentAgentSystemRole = (s: SessionStore) => {
50
- return currentAgentConfig(s).systemRole;
51
- };
52
-
53
53
  const currentAgentModel = (s: SessionStore): LanguageModel => {
54
54
  const config = currentAgentConfig(s);
55
55
 
@@ -4,15 +4,18 @@ import { StateCreator } from 'zustand/vanilla';
4
4
  import { LOADING_FLAT } from '@/const/message';
5
5
  import { fetchChatModel } from '@/services/chatModel';
6
6
  import { fetchPlugin } from '@/services/plugin';
7
- import { SessionStore, agentSelectors, chatSelectors, sessionSelectors } from '@/store/session';
8
- import { getSlicedMessagesWithConfig } from '@/store/session/slices/chat/utils';
7
+ import { SessionStore } from '@/store/session';
9
8
  import { ChatMessage, OpenAIFunctionCall } from '@/types/chatMessage';
10
9
  import { fetchSSE } from '@/utils/fetch';
11
10
  import { isFunctionMessage } from '@/utils/message';
12
11
  import { setNamespace } from '@/utils/storeDebug';
13
12
  import { nanoid } from '@/utils/uuid';
14
13
 
14
+ import { agentSelectors } from '../../agentConfig/selectors';
15
+ import { sessionSelectors } from '../../session/selectors';
15
16
  import { MessageDispatch, messagesReducer } from '../reducers/message';
17
+ import { chatSelectors } from '../selectors';
18
+ import { getSlicedMessagesWithConfig } from '../utils';
16
19
 
17
20
  const t = setNamespace('chat/message');
18
21
 
@@ -24,11 +27,6 @@ export interface ChatMessageAction {
24
27
  * 清除消息
25
28
  */
26
29
  clearMessage: () => void;
27
- /**
28
- * 创建或发送消息
29
- * @param text - 消息文本
30
- */
31
- createOrSendMsg: (text: string) => Promise<void>;
32
30
  /**
33
31
  * 删除消息
34
32
  * @param id - 消息 ID
@@ -86,19 +84,6 @@ export const chatMessage: StateCreator<
86
84
  }
87
85
  },
88
86
 
89
- createOrSendMsg: async (message) => {
90
- if (!message) return;
91
-
92
- const { sendMessage, createSession } = get();
93
- const session = sessionSelectors.currentSession(get());
94
-
95
- if (!session) {
96
- await createSession();
97
- }
98
-
99
- sendMessage(message);
100
- },
101
-
102
87
  deleteMessage: (id) => {
103
88
  get().dispatchMessage({ id, type: 'deleteMessage' });
104
89
  },
@@ -325,4 +310,12 @@ export const chatMessage: StateCreator<
325
310
 
326
311
  await realFetchAIResponse(chats, message.id);
327
312
  },
313
+
314
+ // genShareUrl: () => {
315
+ // const session = sessionSelectors.currentSession(get());
316
+ // if (!session) return '';
317
+ //
318
+ // const agent = session.config;
319
+ // return genShareMessagesUrl(session.chats, agent.systemRole);
320
+ // },
328
321
  });
@@ -2,12 +2,14 @@ import { StateCreator } from 'zustand/vanilla';
2
2
 
3
3
  import { LOADING_FLAT } from '@/const/message';
4
4
  import { promptSummaryTitle } from '@/prompts/chat';
5
- import { SessionStore, chatSelectors, sessionSelectors, topicSelectors } from '@/store/session';
5
+ import { SessionStore } from '@/store/session';
6
6
  import { fetchPresetTaskResult } from '@/utils/fetch';
7
7
  import { setNamespace } from '@/utils/storeDebug';
8
8
  import { nanoid } from '@/utils/uuid';
9
9
 
10
+ import { sessionSelectors } from '../../session/selectors';
10
11
  import { ChatTopicDispatch, topicReducer } from '../reducers/topic';
12
+ import { chatSelectors, topicSelectors } from '../selectors';
11
13
 
12
14
  const t = setNamespace('chat/topic');
13
15
  export interface ChatTopicAction {
@@ -4,7 +4,7 @@ import { ChatMessage } from '@/types/chatMessage';
4
4
 
5
5
  import type { SessionStore } from '../../../store';
6
6
  import { agentSelectors } from '../../agentConfig';
7
- import { sessionSelectors } from '../../session';
7
+ import { sessionSelectors } from '../../session/selectors';
8
8
  import { getSlicedMessagesWithConfig } from '../utils';
9
9
  import { organizeChats } from './utils';
10
10
 
@@ -1,6 +1,6 @@
1
1
  import { encode } from 'gpt-tokenizer';
2
2
 
3
- import { agentSelectors } from '@/store/session';
3
+ import { agentSelectors } from '@/store/session/slices/agentConfig';
4
4
 
5
5
  import type { SessionStore } from '../../../store';
6
6
  import { currentChatsWithHistoryConfig } from './chat';
@@ -1,8 +1,10 @@
1
1
  // 展示在聊天框中的消息
2
- import { SessionStore, sessionSelectors } from '@/store/session';
3
- import { organizeChats } from '@/store/session/slices/chat/selectors/utils';
4
2
  import { ChatTopic } from '@/types/topic';
5
3
 
4
+ import { SessionStore } from '../../../store';
5
+ import { sessionSelectors } from '../../session/selectors';
6
+ import { organizeChats } from './utils';
7
+
6
8
  export const currentTopics = (s: SessionStore): ChatTopic[] => {
7
9
  const session = sessionSelectors.currentSession(s);
8
10
  if (!session) return [];