@lobehub/chat 0.149.3 → 0.149.5

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 (88) hide show
  1. package/.github/FUNDING.yml +1 -1
  2. package/CHANGELOG.md +58 -0
  3. package/package.json +1 -1
  4. package/src/app/chat/(desktop)/features/ChatHeader/Main.tsx +5 -5
  5. package/src/app/chat/(desktop)/features/ChatHeader/Tags.tsx +3 -3
  6. package/src/app/chat/(desktop)/features/ChatInput/Footer/DragUpload.tsx +9 -9
  7. package/src/app/chat/(desktop)/features/ChatInput/Footer/index.tsx +3 -3
  8. package/src/app/chat/(desktop)/features/SideBar/SystemRole/index.tsx +8 -3
  9. package/src/app/chat/(mobile)/mobile/ChatHeader/ChatHeaderTitle.tsx +2 -2
  10. package/src/app/chat/(mobile)/mobile/page.tsx +0 -6
  11. package/src/app/chat/_layout/Desktop/SessionList.tsx +2 -0
  12. package/src/app/chat/features/PageTitle/index.tsx +3 -3
  13. package/src/app/chat/features/PluginTag/PluginStatus.tsx +2 -2
  14. package/src/app/chat/features/SessionListContent/DefaultMode.tsx +4 -2
  15. package/src/app/chat/features/SessionListContent/List/Item/index.tsx +10 -17
  16. package/src/app/chat/features/SessionListContent/index.tsx +2 -0
  17. package/src/app/chat/features/ShareButton/Preview.tsx +15 -11
  18. package/src/app/chat/features/ShareButton/useScreenshot.ts +2 -2
  19. package/src/app/chat/settings/features/EditPage.tsx +10 -7
  20. package/src/app/chat/settings/features/SubmitAgentButton/SubmitAgentModal.tsx +5 -3
  21. package/src/app/metadata.ts +3 -3
  22. package/src/app/settings/(mobile)/features/AvatarBanner.tsx +1 -0
  23. package/src/config/modelProviders/ollama.ts +11 -12
  24. package/src/const/session.ts +1 -0
  25. package/src/database/client/models/session.ts +1 -0
  26. package/src/database/client/models/user.ts +6 -0
  27. package/src/features/ChatInput/ActionBar/FileUpload.tsx +11 -5
  28. package/src/features/ChatInput/ActionBar/History.tsx +3 -3
  29. package/src/features/ChatInput/ActionBar/ModelSwitch.tsx +2 -0
  30. package/src/features/ChatInput/ActionBar/Temperature.tsx +3 -3
  31. package/src/features/ChatInput/ActionBar/Token/TokenTag.tsx +4 -4
  32. package/src/features/ChatInput/ActionBar/Token/index.tsx +3 -3
  33. package/src/features/ChatInput/ActionBar/Tools/ToolItem.tsx +3 -3
  34. package/src/features/ChatInput/ActionBar/Tools/index.tsx +4 -4
  35. package/src/features/ChatInput/STT/browser.tsx +3 -3
  36. package/src/features/ChatInput/STT/openai.tsx +3 -3
  37. package/src/features/ChatInput/useChatInput.ts +3 -3
  38. package/src/features/Conversation/Extras/Assistant.test.tsx +7 -7
  39. package/src/features/Conversation/Extras/Assistant.tsx +3 -3
  40. package/src/features/Conversation/Extras/TTS/index.tsx +3 -3
  41. package/src/features/Conversation/components/ChatItem/ActionsBar.tsx +2 -2
  42. package/src/features/Conversation/components/ChatItem/index.tsx +6 -4
  43. package/src/features/Conversation/hooks/useInitConversation.ts +10 -7
  44. package/src/features/Conversation/index.tsx +6 -3
  45. package/src/features/ModelSwitchPanel/index.tsx +6 -4
  46. package/src/hooks/useTTS.ts +4 -4
  47. package/src/libs/agent-runtime/anthropic/index.test.ts +44 -32
  48. package/src/libs/agent-runtime/anthropic/index.ts +12 -9
  49. package/src/libs/agent-runtime/azureOpenai/index.ts +3 -4
  50. package/src/libs/agent-runtime/bedrock/index.ts +1 -1
  51. package/src/libs/agent-runtime/ollama/index.ts +7 -0
  52. package/src/libs/agent-runtime/perplexity/index.ts +1 -0
  53. package/src/libs/agent-runtime/types/chat.ts +2 -1
  54. package/src/libs/agent-runtime/utils/openaiCompatibleFactory/index.ts +1 -0
  55. package/src/services/chat.ts +18 -15
  56. package/src/services/session/client.ts +19 -0
  57. package/src/services/session/type.ts +2 -0
  58. package/src/store/agent/index.ts +2 -0
  59. package/src/store/agent/initialState.ts +7 -0
  60. package/src/store/agent/selectors.ts +1 -0
  61. package/src/store/{session/slices/agent → agent/slices/chat}/action.test.ts +26 -63
  62. package/src/store/agent/slices/chat/action.ts +107 -0
  63. package/src/store/agent/slices/chat/initialState.ts +14 -0
  64. package/src/store/agent/slices/chat/selectors.test.ts +82 -0
  65. package/src/store/agent/slices/chat/selectors.ts +81 -0
  66. package/src/store/agent/store.ts +27 -0
  67. package/src/store/chat/slices/message/action.test.ts +3 -2
  68. package/src/store/chat/slices/message/action.ts +3 -3
  69. package/src/store/chat/slices/message/selectors.test.ts +9 -2
  70. package/src/store/chat/slices/message/selectors.ts +6 -4
  71. package/src/store/chat/slices/share/action.ts +5 -3
  72. package/src/store/global/slices/preference/selectors.ts +3 -1
  73. package/src/store/session/selectors.ts +1 -2
  74. package/src/store/session/slices/session/action.test.ts +43 -0
  75. package/src/store/session/slices/session/action.ts +28 -18
  76. package/src/store/session/slices/session/helpers.ts +2 -3
  77. package/src/store/session/slices/session/initialState.ts +1 -17
  78. package/src/store/session/slices/session/selectors/index.ts +1 -0
  79. package/src/store/session/slices/session/selectors/list.test.ts +5 -3
  80. package/src/store/session/slices/session/selectors/list.ts +2 -3
  81. package/src/store/session/slices/session/selectors/meta.test.ts +108 -0
  82. package/src/store/session/slices/session/selectors/meta.ts +45 -0
  83. package/src/store/session/store.ts +1 -7
  84. package/src/types/session.ts +1 -0
  85. package/src/store/session/slices/agent/action.ts +0 -84
  86. package/src/store/session/slices/agent/selectors.test.ts +0 -180
  87. package/src/store/session/slices/agent/selectors.ts +0 -129
  88. /package/src/store/{session/slices/agent → agent/slices/chat}/index.ts +0 -0
@@ -0,0 +1,45 @@
1
+ import { t } from 'i18next';
2
+
3
+ import { DEFAULT_AVATAR, DEFAULT_BACKGROUND_COLOR, DEFAULT_INBOX_AVATAR } from '@/const/meta';
4
+ import { SessionStore } from '@/store/session';
5
+ import { MetaData } from '@/types/meta';
6
+ import { merge } from '@/utils/merge';
7
+
8
+ import { sessionSelectors } from './list';
9
+
10
+ // ========== Meta ============== //
11
+ const currentAgentMeta = (s: SessionStore): MetaData => {
12
+ const isInbox = sessionSelectors.isInboxSession(s);
13
+
14
+ const defaultMeta = {
15
+ avatar: isInbox ? DEFAULT_INBOX_AVATAR : DEFAULT_AVATAR,
16
+ backgroundColor: DEFAULT_BACKGROUND_COLOR,
17
+ description: isInbox ? t('inbox.desc', { ns: 'chat' }) : t('noDescription'),
18
+ title: isInbox ? t('inbox.title', { ns: 'chat' }) : t('defaultSession'),
19
+ };
20
+
21
+ const session = sessionSelectors.currentSession(s);
22
+
23
+ return merge(defaultMeta, session?.meta);
24
+ };
25
+
26
+ const currentAgentTitle = (s: SessionStore) => currentAgentMeta(s).title;
27
+ const currentAgentDescription = (s: SessionStore) => currentAgentMeta(s).description;
28
+ const currentAgentAvatar = (s: SessionStore) => currentAgentMeta(s).avatar;
29
+ const currentAgentBackgroundColor = (s: SessionStore) => currentAgentMeta(s).backgroundColor;
30
+
31
+ const getAvatar = (s: MetaData) => s.avatar || DEFAULT_AVATAR;
32
+ const getTitle = (s: MetaData) => s.title || t('defaultSession', { ns: 'common' });
33
+ export const getDescription = (s: MetaData) =>
34
+ s.description || t('noDescription', { ns: 'common' });
35
+
36
+ export const sessionMetaSelectors = {
37
+ currentAgentAvatar,
38
+ currentAgentBackgroundColor,
39
+ currentAgentDescription,
40
+ currentAgentMeta,
41
+ currentAgentTitle,
42
+ getAvatar,
43
+ getDescription,
44
+ getTitle,
45
+ };
@@ -6,21 +6,15 @@ import { StateCreator } from 'zustand/vanilla';
6
6
  import { isDev } from '@/utils/env';
7
7
 
8
8
  import { SessionStoreState, initialState } from './initialState';
9
- import { AgentAction, createAgentSlice } from './slices/agent/action';
10
9
  import { SessionAction, createSessionSlice } from './slices/session/action';
11
10
  import { SessionGroupAction, createSessionGroupSlice } from './slices/sessionGroup/action';
12
11
 
13
12
  // =============== 聚合 createStoreFn ============ //
14
13
 
15
- export interface SessionStore
16
- extends SessionAction,
17
- AgentAction,
18
- SessionGroupAction,
19
- SessionStoreState {}
14
+ export interface SessionStore extends SessionAction, SessionGroupAction, SessionStoreState {}
20
15
 
21
16
  const createStore: StateCreator<SessionStore, [['zustand/devtools', never]]> = (...parameters) => ({
22
17
  ...initialState,
23
- ...createAgentSlice(...parameters),
24
18
  ...createSessionSlice(...parameters),
25
19
  ...createSessionGroupSlice(...parameters),
26
20
  });
@@ -30,6 +30,7 @@ export type SessionGroups = SessionGroupItem[];
30
30
  export interface LobeAgentSession extends BaseDataModel {
31
31
  config: LobeAgentConfig;
32
32
  group?: SessionGroupId;
33
+ model: string;
33
34
  pinned?: boolean;
34
35
  type: LobeSessionType.Agent;
35
36
  }
@@ -1,84 +0,0 @@
1
- import { produce } from 'immer';
2
- import { StateCreator } from 'zustand/vanilla';
3
-
4
- import { sessionService } from '@/services/session';
5
- import { useGlobalStore } from '@/store/global';
6
- import { agentSelectors } from '@/store/session/selectors';
7
- import { LobeAgentConfig } from '@/types/agent';
8
- import { MetaData } from '@/types/meta';
9
-
10
- import { SessionStore } from '../../store';
11
- import { sessionSelectors } from '../session/selectors';
12
-
13
- /**
14
- * 助手接口
15
- */
16
- export interface AgentAction {
17
- removePlugin: (id: string) => void;
18
- togglePlugin: (id: string, open?: boolean) => Promise<void>;
19
- updateAgentConfig: (config: Partial<LobeAgentConfig>) => void;
20
- updateAgentMeta: (meta: Partial<MetaData>) => void;
21
- }
22
-
23
- export const createAgentSlice: StateCreator<
24
- SessionStore,
25
- [['zustand/devtools', never]],
26
- [],
27
- AgentAction
28
- > = (set, get) => ({
29
- removePlugin: async (id) => {
30
- await get().togglePlugin(id, false);
31
- },
32
-
33
- togglePlugin: async (id, open) => {
34
- const originConfig = agentSelectors.currentAgentConfig(get());
35
-
36
- const config = produce(originConfig, (draft) => {
37
- draft.plugins = produce(draft.plugins || [], (plugins) => {
38
- const index = plugins.indexOf(id);
39
- const shouldOpen = open !== undefined ? open : index === -1;
40
-
41
- if (shouldOpen) {
42
- // 如果 open 为 true 或者 id 不存在于 plugins 中,则添加它
43
- if (index === -1) {
44
- plugins.push(id);
45
- }
46
- } else {
47
- // 如果 open 为 false 或者 id 存在于 plugins 中,则移除它
48
- if (index !== -1) {
49
- plugins.splice(index, 1);
50
- }
51
- }
52
- });
53
- });
54
-
55
- get().updateAgentConfig(config);
56
- },
57
- updateAgentConfig: async (config) => {
58
- // if is the inbox session, update the global config
59
- const isInbox = sessionSelectors.isInboxSession(get());
60
- if (isInbox) {
61
- await useGlobalStore.getState().updateDefaultAgent({ config });
62
- } else {
63
- const session = sessionSelectors.currentSession(get());
64
- if (!session) return;
65
-
66
- const { activeId } = get();
67
-
68
- await sessionService.updateSessionConfig(activeId, config);
69
- }
70
-
71
- // trigger store rerender
72
- await get().refreshSessions();
73
- },
74
-
75
- updateAgentMeta: async (meta) => {
76
- const session = sessionSelectors.currentSession(get());
77
- if (!session) return;
78
-
79
- const { activeId, refreshSessions } = get();
80
-
81
- await sessionService.updateSession(activeId, { meta });
82
- await refreshSessions();
83
- },
84
- });
@@ -1,180 +0,0 @@
1
- import { describe, expect, it } from 'vitest';
2
-
3
- import { DEFAULT_AVATAR } from '@/const/meta';
4
- import { DEFAULT_AGENT_CONFIG, DEFAUTT_AGENT_TTS_CONFIG } from '@/const/settings';
5
- import { SessionStore } from '@/store/session';
6
- import { MetaData } from '@/types/meta';
7
- import { LobeAgentSession, LobeSessionType } from '@/types/session';
8
-
9
- import { agentSelectors } from '../agent';
10
-
11
- vi.mock('i18next', () => ({
12
- t: vi.fn((key) => key), // Simplified mock return value
13
- }));
14
-
15
- const mockSessionStore = {
16
- activeId: '1',
17
- sessions: [
18
- {
19
- id: '1',
20
- config: DEFAULT_AGENT_CONFIG,
21
- meta: {
22
- title: 'title1',
23
- description: 'description1',
24
- },
25
- type: LobeSessionType.Agent,
26
- } as LobeAgentSession,
27
- {
28
- id: '2',
29
- meta: {
30
- title: 'title2',
31
- description: 'description2',
32
- },
33
- config: DEFAULT_AGENT_CONFIG,
34
- type: LobeSessionType.Agent,
35
- } as LobeAgentSession,
36
- ],
37
- } as unknown as SessionStore;
38
-
39
- describe('agentSelectors', () => {
40
- describe('currentAgentConfig', () => {
41
- it('should return the merged default and session-specific agent config', () => {
42
- const config = agentSelectors.currentAgentConfig(mockSessionStore);
43
- expect(config).toEqual(expect.objectContaining(mockSessionStore.sessions[0].config));
44
- });
45
- });
46
-
47
- describe('currentAgentModel', () => {
48
- it('should return the model from the agent config', () => {
49
- const model = agentSelectors.currentAgentModel(mockSessionStore);
50
- expect(model).toBe(mockSessionStore.sessions[0].config.model);
51
- });
52
- });
53
-
54
- describe('currentAgentMeta', () => {
55
- it('should return the merged default and session-specific meta data', () => {
56
- const meta = agentSelectors.currentAgentMeta(mockSessionStore);
57
- expect(meta).toEqual(expect.objectContaining(mockSessionStore.sessions[0].meta));
58
- });
59
-
60
- it('should return inbox defaults if it is an inbox session', () => {
61
- // Assume sessionSelectors.isInboxSession() is mocked to return true for this test
62
- const meta = agentSelectors.currentAgentMeta(mockSessionStore);
63
- expect(meta.avatar).toBe(DEFAULT_AVATAR);
64
- });
65
- });
66
-
67
- describe('currentAgentTitle', () => {
68
- it('should return the title from the session meta data', () => {
69
- const title = agentSelectors.currentAgentTitle(mockSessionStore);
70
- expect(title).toBe(mockSessionStore.sessions[0].meta.title);
71
- });
72
- });
73
-
74
- describe('currentAgentDescription', () => {
75
- it('should return the description from the session meta data', () => {
76
- const description = agentSelectors.currentAgentDescription(mockSessionStore);
77
- expect(description).toBe(mockSessionStore.sessions[0].meta.description);
78
- });
79
- });
80
-
81
- // ... More tests for other selectors
82
-
83
- describe('hasSystemRole', () => {
84
- it('should return true if the system role is defined in the agent config', () => {
85
- const hasRole = agentSelectors.hasSystemRole(mockSessionStore);
86
- expect(hasRole).toBe(false);
87
- });
88
-
89
- it('should return false if the system role is not defined in the agent config', () => {
90
- const modifiedSessionStore = {
91
- ...mockSessionStore,
92
- sessions: [
93
- {
94
- ...mockSessionStore.sessions[0],
95
- config: {
96
- ...mockSessionStore.sessions[0].config,
97
- systemRole: 'test',
98
- },
99
- },
100
- ],
101
- };
102
- const hasRole = agentSelectors.hasSystemRole(modifiedSessionStore);
103
- expect(hasRole).toBe(true);
104
- });
105
- });
106
-
107
- describe('currentAgentTTS', () => {
108
- it('should return the TTS config from the agent config', () => {
109
- const ttsConfig = agentSelectors.currentAgentTTS(mockSessionStore);
110
- expect(ttsConfig).toEqual(mockSessionStore.sessions[0].config.tts);
111
- });
112
-
113
- it('should return the default TTS config if none is defined in the agent config', () => {
114
- const modifiedSessionStore = {
115
- ...mockSessionStore,
116
- sessions: [
117
- {
118
- ...mockSessionStore.sessions[0],
119
- config: {
120
- ...mockSessionStore.sessions[0].config,
121
- tts: DEFAUTT_AGENT_TTS_CONFIG,
122
- },
123
- },
124
- ],
125
- };
126
- const ttsConfig = agentSelectors.currentAgentTTS(modifiedSessionStore);
127
- expect(ttsConfig).toEqual(DEFAUTT_AGENT_TTS_CONFIG);
128
- });
129
- });
130
-
131
- describe('currentAgentTTSVoice', () => {
132
- it('should return the appropriate TTS voice based on the service and language', () => {
133
- const lang = 'en';
134
- const ttsVoice = agentSelectors.currentAgentTTSVoice(lang)(mockSessionStore);
135
- expect(ttsVoice).toBe(mockSessionStore.sessions[0].config.tts.voice.openai);
136
- });
137
- });
138
-
139
- describe('getAvatar', () => {
140
- it('should return the avatar from the meta data', () => {
141
- const meta: MetaData = { avatar: 'custom-avatar.png' };
142
- const avatar = agentSelectors.getAvatar(meta);
143
- expect(avatar).toBe(meta.avatar);
144
- });
145
-
146
- it('should return the default avatar if none is defined in the meta data', () => {
147
- const meta: MetaData = {};
148
- const avatar = agentSelectors.getAvatar(meta);
149
- expect(avatar).toBe(DEFAULT_AVATAR);
150
- });
151
- });
152
-
153
- describe('getTitle', () => {
154
- it('should return the title from the meta data', () => {
155
- const meta: MetaData = { title: 'Custom Title' };
156
- const title = agentSelectors.getTitle(meta);
157
- expect(title).toBe(meta.title);
158
- });
159
-
160
- it('should return the default title if none is defined in the meta data', () => {
161
- const meta: MetaData = {};
162
- const title = agentSelectors.getTitle(meta);
163
- expect(title).toBe('defaultSession'); // Assuming translation returns this key
164
- });
165
- });
166
-
167
- describe('getDescription', () => {
168
- it('should return the description from the meta data', () => {
169
- const meta: MetaData = { description: 'Custom Description' };
170
- const description = agentSelectors.getDescription(meta);
171
- expect(description).toBe(meta.description);
172
- });
173
-
174
- it('should return the default description if none is defined in the meta data', () => {
175
- const meta: MetaData = {};
176
- const description = agentSelectors.getDescription(meta);
177
- expect(description).toBe('noDescription'); // Assuming translation returns this key
178
- });
179
- });
180
- });
@@ -1,129 +0,0 @@
1
- import { VoiceList } from '@lobehub/tts';
2
- import { t } from 'i18next';
3
-
4
- import { DEFAULT_AVATAR, DEFAULT_BACKGROUND_COLOR, DEFAULT_INBOX_AVATAR } from '@/const/meta';
5
- import { DEFAULT_AGENT_CONFIG, DEFAUTT_AGENT_TTS_CONFIG } from '@/const/settings';
6
- import { useGlobalStore } from '@/store/global';
7
- import { settingsSelectors } from '@/store/global/selectors';
8
- import { SessionStore } from '@/store/session';
9
- import { LobeAgentTTSConfig } from '@/types/agent';
10
- import { MetaData } from '@/types/meta';
11
- import { merge } from '@/utils/merge';
12
-
13
- import { sessionSelectors } from '../session/selectors';
14
-
15
- // ========== Config ============== //
16
- const currentAgentConfig = (s: SessionStore) => {
17
- const session = sessionSelectors.currentSession(s);
18
-
19
- // if is the inbox session, use the default agent config in global store
20
- if (sessionSelectors.isInboxSession(s)) {
21
- return settingsSelectors.defaultAgentConfig(useGlobalStore.getState());
22
- }
23
-
24
- return merge(DEFAULT_AGENT_CONFIG, session?.config);
25
- };
26
-
27
- const currentAgentSystemRole = (s: SessionStore) => {
28
- return currentAgentConfig(s).systemRole;
29
- };
30
-
31
- const currentAgentModel = (s: SessionStore): string => {
32
- const config = currentAgentConfig(s);
33
-
34
- return config?.model || 'gpt-3.5-turbo';
35
- };
36
-
37
- const currentAgentModelProvider = (s: SessionStore) => {
38
- const config = currentAgentConfig(s);
39
-
40
- return config?.provider;
41
- };
42
-
43
- const currentAgentPlugins = (s: SessionStore) => {
44
- const config = currentAgentConfig(s);
45
-
46
- return config?.plugins || [];
47
- };
48
-
49
- const currentAgentTTS = (s: SessionStore): LobeAgentTTSConfig => {
50
- const config = currentAgentConfig(s);
51
-
52
- return config?.tts || DEFAUTT_AGENT_TTS_CONFIG;
53
- };
54
-
55
- const currentAgentTTSVoice =
56
- (lang: string) =>
57
- (s: SessionStore): string => {
58
- const { voice, ttsService } = currentAgentTTS(s);
59
- const voiceList = new VoiceList(lang);
60
- let currentVoice;
61
- switch (ttsService) {
62
- case 'openai': {
63
- currentVoice = voice.openai || (VoiceList.openaiVoiceOptions?.[0].value as string);
64
- break;
65
- }
66
- case 'edge': {
67
- currentVoice = voice.edge || (voiceList.edgeVoiceOptions?.[0].value as string);
68
- break;
69
- }
70
- case 'microsoft': {
71
- currentVoice = voice.microsoft || (voiceList.microsoftVoiceOptions?.[0].value as string);
72
- break;
73
- }
74
- }
75
- return currentVoice || 'alloy';
76
- };
77
-
78
- // ========== Meta ============== //
79
- const currentAgentMeta = (s: SessionStore): MetaData => {
80
- const isInbox = sessionSelectors.isInboxSession(s);
81
-
82
- const defaultMeta = {
83
- avatar: isInbox ? DEFAULT_INBOX_AVATAR : DEFAULT_AVATAR,
84
- backgroundColor: DEFAULT_BACKGROUND_COLOR,
85
- description: isInbox
86
- ? t('inbox.desc', { ns: 'chat' })
87
- : currentAgentSystemRole(s) || t('noDescription'),
88
- title: isInbox ? t('inbox.title', { ns: 'chat' }) : t('defaultSession'),
89
- };
90
-
91
- const session = sessionSelectors.currentSession(s);
92
-
93
- return merge(defaultMeta, session?.meta);
94
- };
95
-
96
- const currentAgentTitle = (s: SessionStore) => currentAgentMeta(s).title;
97
- const currentAgentDescription = (s: SessionStore) => currentAgentMeta(s).description;
98
- const currentAgentAvatar = (s: SessionStore) => currentAgentMeta(s).avatar;
99
- const currentAgentBackgroundColor = (s: SessionStore) => currentAgentMeta(s).backgroundColor;
100
-
101
- const getAvatar = (s: MetaData) => s.avatar || DEFAULT_AVATAR;
102
- const getTitle = (s: MetaData) => s.title || t('defaultSession', { ns: 'common' });
103
- export const getDescription = (s: MetaData) =>
104
- s.description || t('noDescription', { ns: 'common' });
105
-
106
- const hasSystemRole = (s: SessionStore) => {
107
- const config = currentAgentConfig(s);
108
-
109
- return !!config.systemRole;
110
- };
111
-
112
- export const agentSelectors = {
113
- currentAgentAvatar,
114
- currentAgentBackgroundColor,
115
- currentAgentConfig,
116
- currentAgentDescription,
117
- currentAgentMeta,
118
- currentAgentModel,
119
- currentAgentModelProvider,
120
- currentAgentPlugins,
121
- currentAgentSystemRole,
122
- currentAgentTTS,
123
- currentAgentTTSVoice,
124
- currentAgentTitle,
125
- getAvatar,
126
- getDescription,
127
- getTitle,
128
- hasSystemRole,
129
- };