@lobehub/lobehub 2.0.0-next.267 → 2.0.0-next.269

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 (135) hide show
  1. package/.cursor/rules/microcopy-cn.mdc +75 -63
  2. package/.cursor/rules/microcopy-en.mdc +4 -8
  3. package/CHANGELOG.md +50 -0
  4. package/README.md +8 -8
  5. package/README.zh-CN.md +8 -8
  6. package/apps/desktop/src/main/core/browser/Browser.ts +6 -0
  7. package/apps/desktop/src/main/locales/default/common.ts +2 -2
  8. package/changelog/v1.json +10 -0
  9. package/docs/development/database-schema.dbml +4 -0
  10. package/e2e/CLAUDE.md +9 -8
  11. package/e2e/cucumber.config.js +1 -0
  12. package/e2e/src/features/page/README.md +118 -0
  13. package/e2e/src/features/page/crud.feature +62 -0
  14. package/e2e/src/features/page/editor-content.feature +93 -0
  15. package/e2e/src/features/page/editor-meta.feature +60 -0
  16. package/e2e/src/steps/agent/conversation.steps.ts +4 -4
  17. package/e2e/src/steps/home/sidebarAgent.steps.ts +91 -94
  18. package/e2e/src/steps/home/sidebarGroup.steps.ts +4 -4
  19. package/e2e/src/steps/hooks.ts +2 -0
  20. package/e2e/src/steps/page/editor-content.steps.ts +344 -0
  21. package/e2e/src/steps/page/editor-meta.steps.ts +410 -0
  22. package/e2e/src/steps/page/page-crud.steps.ts +363 -0
  23. package/e2e/src/support/world.ts +12 -0
  24. package/locales/ar/file.json +2 -0
  25. package/locales/bg-BG/file.json +2 -0
  26. package/locales/de-DE/file.json +2 -0
  27. package/locales/en-US/auth.json +1 -1
  28. package/locales/en-US/file.json +2 -0
  29. package/locales/en-US/metadata.json +2 -2
  30. package/locales/es-ES/file.json +2 -0
  31. package/locales/fa-IR/file.json +2 -0
  32. package/locales/fr-FR/file.json +2 -0
  33. package/locales/it-IT/file.json +2 -0
  34. package/locales/ja-JP/file.json +2 -0
  35. package/locales/ko-KR/file.json +2 -0
  36. package/locales/nl-NL/file.json +2 -0
  37. package/locales/pl-PL/file.json +2 -0
  38. package/locales/pt-BR/file.json +2 -0
  39. package/locales/ru-RU/file.json +2 -0
  40. package/locales/tr-TR/file.json +2 -0
  41. package/locales/vi-VN/file.json +2 -0
  42. package/locales/zh-CN/file.json +2 -0
  43. package/locales/zh-TW/file.json +2 -0
  44. package/package.json +1 -1
  45. package/packages/builtin-agents/src/agents/agent-builder/index.ts +1 -1
  46. package/packages/builtin-agents/src/agents/group-agent-builder/index.ts +1 -1
  47. package/packages/builtin-agents/src/agents/page-agent/index.ts +1 -1
  48. package/packages/const/src/settings/group.ts +0 -10
  49. package/packages/database/migrations/0068_update_group_data.sql +4 -0
  50. package/packages/database/migrations/meta/0068_snapshot.json +9588 -0
  51. package/packages/database/migrations/meta/_journal.json +7 -0
  52. package/packages/database/src/models/__tests__/chatGroup.test.ts +5 -7
  53. package/packages/database/src/models/__tests__/knowledgeBase.test.ts +185 -0
  54. package/packages/database/src/models/knowledgeBase.ts +67 -3
  55. package/packages/database/src/repositories/agentGroup/index.test.ts +23 -29
  56. package/packages/database/src/repositories/agentGroup/index.ts +4 -9
  57. package/packages/database/src/repositories/knowledge/index.ts +3 -3
  58. package/packages/database/src/schemas/chatGroup.ts +4 -3
  59. package/packages/database/src/types/chatGroup.ts +0 -7
  60. package/packages/types/src/agentGroup/index.ts +30 -9
  61. package/packages/utils/src/index.ts +1 -0
  62. package/packages/utils/src/platform.ts +35 -3
  63. package/src/app/[variants]/(desktop)/desktop-onboarding/_layout/index.tsx +30 -22
  64. package/src/app/[variants]/(desktop)/desktop-onboarding/_layout/style.ts +8 -5
  65. package/src/app/[variants]/(main)/_layout/DesktopLayoutContainer.tsx +2 -3
  66. package/src/app/[variants]/(main)/home/_layout/Body/Agent/ModalProvider.tsx +9 -32
  67. package/src/app/[variants]/(main)/home/_layout/hooks/useCreateMenuItems.tsx +3 -37
  68. package/src/app/[variants]/(main)/home/_layout/hooks/useSessionGroupMenuItems.tsx +7 -53
  69. package/src/app/[variants]/(main)/home/features/RecentPage/List.tsx +2 -1
  70. package/src/app/[variants]/(main)/resource/features/DndContextWrapper.tsx +1 -1
  71. package/src/app/[variants]/(main)/resource/library/_layout/Sidebar.tsx +2 -2
  72. package/src/app/[variants]/(main)/resource/library/features/LibraryMenu.tsx +2 -2
  73. package/src/app/[variants]/(mobile)/chat/settings/features/SettingButton.tsx +2 -12
  74. package/src/components/ChatGroupWizard/ChatGroupWizard.tsx +5 -27
  75. package/src/components/DragUpload/index.tsx +24 -27
  76. package/src/components/MemberSelectionModal/MemberSelectionModal.tsx +2 -11
  77. package/src/features/CommandMenu/useCommandMenu.ts +4 -14
  78. package/src/features/ElectronTitlebar/SimpleTitleBar.tsx +31 -0
  79. package/src/features/ElectronTitlebar/index.tsx +1 -0
  80. package/src/features/ResourceManager/components/Editor/index.tsx +2 -3
  81. package/src/features/ResourceManager/components/Explorer/Header/index.tsx +13 -17
  82. package/src/features/ResourceManager/components/Explorer/ItemDropdown/useFileItemDropdown.tsx +1 -1
  83. package/src/features/ResourceManager/components/Explorer/ListView/ListItem/TruncatedFileName.tsx +130 -0
  84. package/src/features/ResourceManager/components/Explorer/ListView/ListItem/index.tsx +36 -4
  85. package/src/features/ResourceManager/components/Explorer/ListView/Skeleton.tsx +4 -3
  86. package/src/features/ResourceManager/components/Explorer/ListView/index.tsx +58 -2
  87. package/src/features/ResourceManager/components/Explorer/MasonryView/index.tsx +58 -6
  88. package/src/features/ResourceManager/components/Explorer/MoveToFolderModal.tsx +2 -5
  89. package/src/features/ResourceManager/components/Explorer/ToolBar/BatchActionsDropdown.tsx +9 -5
  90. package/src/features/ResourceManager/components/Explorer/index.tsx +11 -56
  91. package/src/features/ResourceManager/components/Header/AddButton.tsx +5 -6
  92. package/src/features/ResourceManager/components/LibraryHierarchy/HierarchyNode.tsx +382 -0
  93. package/src/features/ResourceManager/components/LibraryHierarchy/index.tsx +396 -0
  94. package/src/features/ResourceManager/components/LibraryHierarchy/styles.ts +19 -0
  95. package/src/features/ResourceManager/components/LibraryHierarchy/treeState.ts +178 -0
  96. package/src/features/ResourceManager/components/LibraryHierarchy/types.ts +10 -0
  97. package/src/features/ResourceManager/index.tsx +3 -0
  98. package/src/layout/GlobalProvider/GroupWizardProvider.tsx +6 -29
  99. package/src/locales/default/auth.ts +1 -1
  100. package/src/locales/default/file.ts +2 -0
  101. package/src/locales/default/metadata.ts +2 -2
  102. package/src/server/modules/AgentRuntime/AgentRuntimeCoordinator.ts +30 -30
  103. package/src/server/modules/AgentRuntime/AgentStateManager.ts +23 -23
  104. package/src/server/modules/AgentRuntime/InMemoryAgentStateManager.ts +16 -16
  105. package/src/server/modules/AgentRuntime/InMemoryStreamEventManager.ts +13 -13
  106. package/src/server/modules/AgentRuntime/RuntimeExecutors.ts +2 -2
  107. package/src/server/modules/AgentRuntime/StreamEventManager.ts +18 -18
  108. package/src/server/modules/AgentRuntime/types.ts +21 -21
  109. package/src/server/routers/lambda/__tests__/agentGroup.test.ts +8 -8
  110. package/src/server/routers/lambda/agentGroup.ts +10 -12
  111. package/src/server/services/document/index.ts +1 -0
  112. package/src/store/agentGroup/slices/curd.test.ts +4 -4
  113. package/src/store/file/slices/fileManager/action.ts +12 -4
  114. package/src/store/home/slices/homeInput/action.ts +0 -3
  115. package/src/store/session/slices/session/action.ts +5 -9
  116. package/src/utils/platform.ts +2 -0
  117. package/src/app/[variants]/(mobile)/chat/settings/features/AgentTeamSettings/index.tsx +0 -95
  118. package/src/features/GroupChatSettings/AgentCard.tsx +0 -154
  119. package/src/features/GroupChatSettings/AgentTeamChatSettings.tsx +0 -179
  120. package/src/features/GroupChatSettings/AgentTeamMembersSettings.tsx +0 -244
  121. package/src/features/GroupChatSettings/AgentTeamMetaSettings.tsx +0 -94
  122. package/src/features/GroupChatSettings/AgentTeamSettings.tsx +0 -54
  123. package/src/features/GroupChatSettings/GroupCategory/index.tsx +0 -30
  124. package/src/features/GroupChatSettings/GroupCategory/useGroupCategory.tsx +0 -42
  125. package/src/features/GroupChatSettings/GroupChatSettingsProvider.tsx +0 -19
  126. package/src/features/GroupChatSettings/HostMemberCard.tsx +0 -113
  127. package/src/features/GroupChatSettings/StoreUpdater.tsx +0 -34
  128. package/src/features/GroupChatSettings/hooks/useGroupChatSettings.ts +0 -25
  129. package/src/features/GroupChatSettings/index.ts +0 -16
  130. package/src/features/GroupChatSettings/store/action.ts +0 -105
  131. package/src/features/GroupChatSettings/store/index.ts +0 -18
  132. package/src/features/GroupChatSettings/store/initialState.ts +0 -23
  133. package/src/features/GroupChatSettings/store/selectors.ts +0 -13
  134. package/src/features/ResourceManager/components/Tree/index.tsx +0 -883
  135. /package/src/features/ResourceManager/components/{Tree → LibraryHierarchy}/TreeSkeleton.tsx +0 -0
@@ -25,18 +25,50 @@ export const browserInfo = {
25
25
 
26
26
  export const isMacOS = () => getPlatform() === 'Mac OS';
27
27
 
28
+ /**
29
+ * Get macOS Darwin major version number
30
+ * @returns Darwin major version (e.g., 25, 26) or 0 if not available
31
+ */
32
+ export const getDarwinMajorVersion = (): number => {
33
+ if (isOnServerSide || typeof window === 'undefined') return 0;
34
+
35
+ // In Electron environment, use window.lobeEnv.darwinMajorVersion if available
36
+ if (typeof (window as any)?.lobeEnv?.darwinMajorVersion === 'number') {
37
+ return (window as any).lobeEnv.darwinMajorVersion;
38
+ }
39
+
40
+ // In web environment, try to parse from userAgent
41
+ if (typeof navigator !== 'undefined') {
42
+ const match = navigator.userAgent.match(/Mac OS X (\d+)[._](\d+)/);
43
+ if (match) {
44
+ return parseInt(match[1], 10);
45
+ }
46
+ }
47
+
48
+ return 0;
49
+ };
50
+
28
51
  /**
29
52
  *
30
53
  * We can't use it to detect the macOS real version, and we also don't know if it's macOS 26, only an estimated value.
31
- * @returns true if the current browser is macOS and the version is 10.15 or later
54
+ * @returns true if the current browser is macOS and the version is 10.15 or later (web) or darwinMajorVersion >= 25 (Electron)
32
55
  */
33
56
  export const isMacOSWithLargeWindowBorders = () => {
34
57
  if (isOnServerSide || typeof navigator === 'undefined') return false;
35
58
 
36
- // keep consistent with the original logic: only for macOS on web (exclude Electron)
59
+ // Check if we're in Electron environment
37
60
  const isElectron =
38
61
  /Electron\//.test(navigator.userAgent) || Boolean((window as any)?.process?.type);
39
- if (isElectron || !isMacOS()) return false;
62
+
63
+ // In Electron environment, check darwinMajorVersion from window.lobeEnv
64
+ if (isElectron) {
65
+ const darwinMajorVersion = getDarwinMajorVersion();
66
+ // macOS 25+ has large window borders
67
+ return darwinMajorVersion >= 25;
68
+ }
69
+
70
+ // keep consistent with the original logic: only for macOS on web (exclude Electron)
71
+ if (!isMacOS()) return false;
40
72
 
41
73
  const match = navigator.userAgent.match(/Mac OS X (\d+)[._](\d+)/);
42
74
  if (!match) return false;
@@ -5,6 +5,7 @@ import { Divider } from 'antd';
5
5
  import { cx } from 'antd-style';
6
6
  import type { FC, PropsWithChildren } from 'react';
7
7
 
8
+ import { SimpleTitleBar, TITLE_BAR_HEIGHT } from '@/features/ElectronTitlebar';
8
9
  import LangButton from '@/features/User/UserPanel/LangButton';
9
10
  import ThemeButton from '@/features/User/UserPanel/ThemeButton';
10
11
  import { useIsDark } from '@/hooks/useIsDark';
@@ -14,36 +15,43 @@ import { styles } from './style';
14
15
  const OnboardingContainer: FC<PropsWithChildren> = ({ children }) => {
15
16
  const isDarkMode = useIsDark();
16
17
  return (
17
- <Flexbox className={styles.outerContainer} height={'100%'} padding={8} width={'100%'}>
18
+ <Flexbox height={'100%'} width={'100%'}>
19
+ <SimpleTitleBar />
18
20
  <Flexbox
19
- className={cx(isDarkMode ? styles.innerContainerDark : styles.innerContainerLight)}
20
- height={'100%'}
21
+ className={styles.outerContainer}
22
+ height={`calc(100% - ${TITLE_BAR_HEIGHT}px)`}
23
+ style={{ paddingBottom: 8, paddingInline: 8 }}
21
24
  width={'100%'}
22
25
  >
23
26
  <Flexbox
24
- align={'center'}
25
- className={cx(styles.drag)}
26
- gap={8}
27
- horizontal
28
- justify={'space-between'}
29
- padding={16}
27
+ className={cx(isDarkMode ? styles.innerContainerDark : styles.innerContainerLight)}
28
+ height={'100%'}
30
29
  width={'100%'}
31
30
  >
32
- <div />
33
- <Flexbox align={'center'} horizontal>
34
- <LangButton placement={'bottomRight'} size={18} />
35
- <Divider className={styles.divider} orientation={'vertical'} />
36
- <ThemeButton placement={'bottomRight'} size={18} />
31
+ <Flexbox
32
+ align={'center'}
33
+ gap={8}
34
+ horizontal
35
+ justify={'space-between'}
36
+ padding={16}
37
+ width={'100%'}
38
+ >
39
+ <div />
40
+ <Flexbox align={'center'} horizontal>
41
+ <LangButton placement={'bottomRight'} size={18} />
42
+ <Divider className={styles.divider} orientation={'vertical'} />
43
+ <ThemeButton placement={'bottomRight'} size={18} />
44
+ </Flexbox>
37
45
  </Flexbox>
46
+ <Center height={'100%'} padding={16} width={'100%'}>
47
+ {children}
48
+ </Center>
49
+ <Center padding={24}>
50
+ <Text align={'center'} type={'secondary'}>
51
+ © 2025 LobeHub. All rights reserved.
52
+ </Text>
53
+ </Center>
38
54
  </Flexbox>
39
- <Center height={'100%'} padding={16} width={'100%'}>
40
- {children}
41
- </Center>
42
- <Center padding={24}>
43
- <Text align={'center'} type={'secondary'}>
44
- © 2025 LobeHub. All rights reserved.
45
- </Text>
46
- </Center>
47
55
  </Flexbox>
48
56
  </Flexbox>
49
57
  );
@@ -1,14 +1,13 @@
1
1
  import { createStaticStyles } from 'antd-style';
2
2
 
3
+ import { isMacOSWithLargeWindowBorders } from '@/utils/platform';
4
+
3
5
  export const styles = createStaticStyles(({ css, cssVar }) => ({
4
6
  // Divider 样式
5
7
  divider: css`
6
8
  height: 24px;
7
9
  `,
8
10
 
9
- drag: css`
10
- -webkit-app-region: drag;
11
- `,
12
11
  // 内层容器 - 深色模式
13
12
  innerContainerDark: css`
14
13
  position: relative;
@@ -16,7 +15,9 @@ export const styles = createStaticStyles(({ css, cssVar }) => ({
16
15
  overflow: hidden;
17
16
 
18
17
  border: 1px solid ${cssVar.colorBorderSecondary};
19
- border-radius: ${cssVar.borderRadius};
18
+ border-radius: ${!isMacOSWithLargeWindowBorders()
19
+ ? cssVar.borderRadius
20
+ : `${cssVar.borderRadius} 12px ${cssVar.borderRadius} 12px`};
20
21
 
21
22
  background: ${cssVar.colorBgContainer};
22
23
  `,
@@ -28,7 +29,9 @@ export const styles = createStaticStyles(({ css, cssVar }) => ({
28
29
  overflow: hidden;
29
30
 
30
31
  border: 1px solid ${cssVar.colorBorder};
31
- border-radius: ${cssVar.borderRadius};
32
+ border-radius: ${!isMacOSWithLargeWindowBorders()
33
+ ? cssVar.borderRadius
34
+ : `${cssVar.borderRadius} 12px ${cssVar.borderRadius} 12px`};
32
35
 
33
36
  background: ${cssVar.colorBgContainer};
34
37
  `,
@@ -6,7 +6,7 @@ import { isDesktop } from '@/const/version';
6
6
  import { useIsDark } from '@/hooks/useIsDark';
7
7
  import { useGlobalStore } from '@/store/global';
8
8
  import { systemStatusSelectors } from '@/store/global/selectors';
9
- import { isMacOSWithLargeWindowBorders } from '@/utils/platform';
9
+ import { getDarwinMajorVersion, isMacOSWithLargeWindowBorders } from '@/utils/platform';
10
10
 
11
11
  import { styles } from './DesktopLayoutContainer/style';
12
12
 
@@ -24,8 +24,7 @@ const DesktopLayoutContainer: FC<PropsWithChildren> = ({ children }) => {
24
24
  );
25
25
 
26
26
  const innerCssVariables = useMemo<Record<string, string>>(() => {
27
- const darwinMajorVersion =
28
- typeof window !== 'undefined' ? (window.lobeEnv?.darwinMajorVersion ?? 0) : 0;
27
+ const darwinMajorVersion = getDarwinMajorVersion();
29
28
 
30
29
  const borderRadius = darwinMajorVersion >= 25 ? '12px' : cssVar.borderRadius;
31
30
  const borderBottomRightRadius =
@@ -23,26 +23,13 @@ interface AgentModalContextValue {
23
23
 
24
24
  interface GroupWizardCallbacks {
25
25
  onCancel?: () => void;
26
- onCreateCustom?: (
27
- selectedAgents: string[],
28
- hostConfig?: { model?: string; provider?: string },
29
- enableSupervisor?: boolean,
30
- ) => Promise<void>;
31
- onCreateFromTemplate?: (
32
- templateId: string,
33
- hostConfig?: { model?: string; provider?: string },
34
- enableSupervisor?: boolean,
35
- selectedMemberTitles?: string[],
36
- ) => Promise<void>;
26
+ onCreateCustom?: (selectedAgents: string[]) => Promise<void>;
27
+ onCreateFromTemplate?: (templateId: string, selectedMemberTitles?: string[]) => Promise<void>;
37
28
  }
38
29
 
39
30
  interface MemberSelectionCallbacks {
40
31
  onCancel?: () => void;
41
- onConfirm?: (
42
- selectedAgents: string[],
43
- hostConfig?: { model?: string; provider?: string },
44
- enableSupervisor?: boolean,
45
- ) => Promise<void>;
32
+ onConfirm?: (selectedAgents: string[]) => Promise<void>;
46
33
  }
47
34
 
48
35
  const AgentModalContext = createContext<AgentModalContextValue | null>(null);
@@ -131,21 +118,11 @@ export const AgentModalProvider = memo<AgentModalProviderProps>(({ children }) =
131
118
  groupWizardCallbacks.onCancel?.();
132
119
  setGroupWizardOpen(false);
133
120
  }}
134
- onCreateCustom={async (selectedAgents, hostConfig, enableSupervisor) => {
135
- await groupWizardCallbacks.onCreateCustom?.(selectedAgents, hostConfig, enableSupervisor);
121
+ onCreateCustom={async (selectedAgents: string[]) => {
122
+ await groupWizardCallbacks.onCreateCustom?.(selectedAgents);
136
123
  }}
137
- onCreateFromTemplate={async (
138
- templateId,
139
- hostConfig,
140
- enableSupervisor,
141
- selectedMemberTitles,
142
- ) => {
143
- await groupWizardCallbacks.onCreateFromTemplate?.(
144
- templateId,
145
- hostConfig,
146
- enableSupervisor,
147
- selectedMemberTitles,
148
- );
124
+ onCreateFromTemplate={async (templateId: string, selectedMemberTitles?: string[]) => {
125
+ await groupWizardCallbacks.onCreateFromTemplate?.(templateId, selectedMemberTitles);
149
126
  }}
150
127
  open={groupWizardOpen}
151
128
  />
@@ -156,8 +133,8 @@ export const AgentModalProvider = memo<AgentModalProviderProps>(({ children }) =
156
133
  memberSelectionCallbacks.onCancel?.();
157
134
  setMemberSelectionOpen(false);
158
135
  }}
159
- onConfirm={async (selectedAgents, hostConfig, enableSupervisor) => {
160
- await memberSelectionCallbacks.onConfirm?.(selectedAgents, hostConfig, enableSupervisor);
136
+ onConfirm={async (selectedAgents: string[]) => {
137
+ await memberSelectionCallbacks.onConfirm?.(selectedAgents);
161
138
  }}
162
139
  open={memberSelectionOpen}
163
140
  />
@@ -16,11 +16,6 @@ import { useAgentGroupStore } from '@/store/agentGroup';
16
16
  import { useHomeStore } from '@/store/home';
17
17
  import { usePageStore } from '@/store/page';
18
18
 
19
- interface HostConfig {
20
- model?: string;
21
- provider?: string;
22
- }
23
-
24
19
  interface CreateAgentOptions {
25
20
  groupId?: string;
26
21
  isPinned?: boolean;
@@ -104,12 +99,7 @@ export const useCreateMenuItems = () => {
104
99
  * Uses backend batch creation for better performance and consistency
105
100
  */
106
101
  const createGroupFromTemplate = useCallback(
107
- async (
108
- templateId: string,
109
- hostConfig?: HostConfig,
110
- enableSupervisor?: boolean,
111
- selectedMemberTitles?: string[],
112
- ) => {
102
+ async (templateId: string, selectedMemberTitles?: string[]) => {
113
103
  setIsCreatingGroup(true);
114
104
  try {
115
105
  const template = groupTemplates.find((t) => t.id === templateId);
@@ -134,16 +124,6 @@ export const useCreateMenuItems = () => {
134
124
  // Use batch creation endpoint - creates all agents and group in one request
135
125
  const { groupId } = await chatGroupService.createGroupWithMembers(
136
126
  {
137
- config: {
138
- ...(hostConfig
139
- ? {
140
- orchestratorModel: hostConfig.model,
141
- orchestratorProvider: hostConfig.provider,
142
- }
143
- : {}),
144
- enableSupervisor: enableSupervisor ?? true,
145
- scene: DEFAULT_CHAT_GROUP_CHAT_CONFIG.scene,
146
- },
147
127
  title: template.title,
148
128
  },
149
129
  memberConfigs,
@@ -172,28 +152,14 @@ export const useCreateMenuItems = () => {
172
152
  * Create group with members
173
153
  */
174
154
  const createGroupWithMembers = useCallback(
175
- async (
176
- selectedAgents: string[],
177
- groupTitle?: string,
178
- hostConfig?: HostConfig,
179
- enableSupervisor?: boolean,
180
- ) => {
155
+ async (selectedAgents: string[], groupTitle?: string) => {
181
156
  setIsCreatingGroup(true);
182
157
  try {
183
158
  const title = groupTitle || t('defaultGroupChat');
184
159
 
185
160
  await createGroup(
186
161
  {
187
- config: {
188
- ...DEFAULT_CHAT_GROUP_CHAT_CONFIG,
189
- ...(hostConfig
190
- ? {
191
- orchestratorModel: hostConfig.model,
192
- orchestratorProvider: hostConfig.provider,
193
- }
194
- : {}),
195
- enableSupervisor: enableSupervisor ?? true,
196
- },
162
+ config: DEFAULT_CHAT_GROUP_CHAT_CONFIG,
197
163
  title,
198
164
  },
199
165
  selectedAgents,
@@ -18,11 +18,6 @@ const styles = createStaticStyles(({ css }) => ({
18
18
  `,
19
19
  }));
20
20
 
21
- interface HostConfig {
22
- model?: string;
23
- provider?: string;
24
- }
25
-
26
21
  /**
27
22
  * Hook for generating menu items for session group containers
28
23
  * Used in List/Group/Actions.tsx
@@ -153,11 +148,7 @@ export const useSessionGroupMenuItems = () => {
153
148
  _groupId: string,
154
149
  onOpenMemberSelection: (callbacks: {
155
150
  onCancel: () => void;
156
- onConfirm: (
157
- selectedAgents: string[],
158
- hostConfig?: HostConfig,
159
- enableSupervisor?: boolean,
160
- ) => Promise<void>;
151
+ onConfirm: (selectedAgents: string[]) => Promise<void>;
161
152
  }) => void,
162
153
  ): ItemType => {
163
154
  const iconElement = <Icon icon={FolderPenIcon} />;
@@ -170,21 +161,12 @@ export const useSessionGroupMenuItems = () => {
170
161
 
171
162
  onOpenMemberSelection({
172
163
  onCancel: () => {},
173
- onConfirm: async (selectedAgents, hostConfig, enableSupervisor) => {
164
+ onConfirm: async (selectedAgents) => {
174
165
  setIsCreatingGroup(true);
175
166
  try {
176
167
  await createGroup(
177
168
  {
178
- config: {
179
- ...DEFAULT_CHAT_GROUP_CHAT_CONFIG,
180
- ...(hostConfig
181
- ? {
182
- orchestratorModel: hostConfig.model,
183
- orchestratorProvider: hostConfig.provider,
184
- }
185
- : {}),
186
- enableSupervisor: enableSupervisor ?? true,
187
- },
169
+ config: DEFAULT_CHAT_GROUP_CHAT_CONFIG,
188
170
  title: 'New Group Chat',
189
171
  },
190
172
  selectedAgents,
@@ -208,12 +190,7 @@ export const useSessionGroupMenuItems = () => {
208
190
  * Internal helper function used by create menu items
209
191
  */
210
192
  const createGroupFromTemplate = useCallback(
211
- async (
212
- templateId: string,
213
- hostConfig?: HostConfig,
214
- enableSupervisor?: boolean,
215
- selectedMemberTitles?: string[],
216
- ) => {
193
+ async (templateId: string, selectedMemberTitles?: string[]) => {
217
194
  setIsCreatingGroup(true);
218
195
  try {
219
196
  const template = groupTemplates.find((t) => t.id === templateId);
@@ -258,16 +235,7 @@ export const useSessionGroupMenuItems = () => {
258
235
 
259
236
  await createGroup(
260
237
  {
261
- config: {
262
- ...DEFAULT_CHAT_GROUP_CHAT_CONFIG,
263
- ...(hostConfig
264
- ? {
265
- orchestratorModel: hostConfig.model,
266
- orchestratorProvider: hostConfig.provider,
267
- }
268
- : {}),
269
- enableSupervisor: enableSupervisor ?? true,
270
- },
238
+ config: DEFAULT_CHAT_GROUP_CHAT_CONFIG,
271
239
  title: template.title,
272
240
  },
273
241
  memberAgentIds,
@@ -290,28 +258,14 @@ export const useSessionGroupMenuItems = () => {
290
258
  * Internal helper function used by create menu items
291
259
  */
292
260
  const createGroupWithMembers = useCallback(
293
- async (
294
- selectedAgents: string[],
295
- groupTitle?: string,
296
- hostConfig?: HostConfig,
297
- enableSupervisor?: boolean,
298
- ) => {
261
+ async (selectedAgents: string[], groupTitle?: string) => {
299
262
  setIsCreatingGroup(true);
300
263
  try {
301
264
  const title = groupTitle || t('defaultGroupChat');
302
265
 
303
266
  await createGroup(
304
267
  {
305
- config: {
306
- ...DEFAULT_CHAT_GROUP_CHAT_CONFIG,
307
- ...(hostConfig
308
- ? {
309
- orchestratorModel: hostConfig.model,
310
- orchestratorProvider: hostConfig.provider,
311
- }
312
- : {}),
313
- enableSupervisor: enableSupervisor ?? true,
314
- },
268
+ config: DEFAULT_CHAT_GROUP_CHAT_CONFIG,
315
269
  title,
316
270
  },
317
271
  selectedAgents,
@@ -7,6 +7,7 @@ import GroupSkeleton from '@/app/[variants]/(main)/home/features/components/Grou
7
7
  import { RECENT_BLOCK_SIZE } from '@/app/[variants]/(main)/home/features/const';
8
8
  import { useHomeStore } from '@/store/home';
9
9
  import { homeRecentSelectors } from '@/store/home/selectors';
10
+ import { standardizeIdentifier } from '@/utils/identifier';
10
11
 
11
12
  import RecentPageItem from './Item';
12
13
 
@@ -22,7 +23,7 @@ const RecentPageList = memo(() => {
22
23
  }
23
24
 
24
25
  return documents.map((document) => {
25
- const pageUrl = `/page/${document.id}`;
26
+ const pageUrl = `/page/${standardizeIdentifier(document.id)}`;
26
27
 
27
28
  return (
28
29
  <Link
@@ -17,7 +17,7 @@ import { createPortal } from 'react-dom';
17
17
  import { useTranslation } from 'react-i18next';
18
18
 
19
19
  import FileIcon from '@/components/FileIcon';
20
- import { clearTreeFolderCache } from '@/features/ResourceManager/components/Tree';
20
+ import { clearTreeFolderCache } from '@/features/ResourceManager/components/LibraryHierarchy';
21
21
  import { useFileStore } from '@/store/file';
22
22
 
23
23
  import { useResourceManagerStore } from './store';
@@ -4,14 +4,14 @@ import { memo } from 'react';
4
4
 
5
5
  import { NavPanelPortal } from '@/features/NavPanel';
6
6
  import SideBarLayout from '@/features/NavPanel/SideBarLayout';
7
- import FileTree from '@/features/ResourceManager/components/Tree';
7
+ import LibraryHierarchy from '@/features/ResourceManager/components/LibraryHierarchy';
8
8
 
9
9
  import Header from './Header';
10
10
 
11
11
  const Sidebar = memo(() => {
12
12
  return (
13
13
  <NavPanelPortal navKey="resourceLibrary">
14
- <SideBarLayout body={<FileTree />} header={<Header />} />
14
+ <SideBarLayout body={<LibraryHierarchy />} header={<Header />} />
15
15
  </NavPanelPortal>
16
16
  );
17
17
  });
@@ -3,7 +3,7 @@
3
3
  import { Flexbox } from '@lobehub/ui';
4
4
  import { memo } from 'react';
5
5
 
6
- import FileTree from '@/features/ResourceManager/components/Tree';
6
+ import LibraryHierarchy from '@/features/ResourceManager/components/LibraryHierarchy';
7
7
 
8
8
  import Head from '../_layout/Header/LibraryHead';
9
9
 
@@ -13,7 +13,7 @@ const Menu = memo<{ id: string }>(({ id }) => {
13
13
  <Flexbox paddingInline={12}>
14
14
  <Head id={id} />
15
15
  </Flexbox>
16
- <FileTree />
16
+ <LibraryHierarchy />
17
17
  </Flexbox>
18
18
  );
19
19
  });
@@ -8,9 +8,7 @@ import { useTranslation } from 'react-i18next';
8
8
 
9
9
  import { DESKTOP_HEADER_ICON_SIZE, MOBILE_HEADER_ICON_SIZE } from '@/const/layoutTokens';
10
10
  import { useOpenChatSettings } from '@/hooks/useInterceptingRoutes';
11
- import { useAgentGroupStore } from '@/store/agentGroup';
12
11
  import { useSessionStore } from '@/store/session';
13
- import { sessionSelectors } from '@/store/session/selectors';
14
12
  import { useUserStore } from '@/store/user';
15
13
  import { settingsSelectors } from '@/store/user/selectors';
16
14
  import { HotkeyEnum } from '@/types/hotkey';
@@ -19,26 +17,18 @@ const AgentSettingsEditor = dynamic(() => import('@/app/[variants]/(main)/agent/
19
17
  ssr: false,
20
18
  });
21
19
 
22
- const AgentTeamSettings = dynamic(() => import('./AgentTeamSettings'), {
23
- ssr: false,
24
- });
25
-
26
20
  const SettingButton = memo<{ mobile?: boolean }>(({ mobile }) => {
27
21
  const hotkey = useUserStore(settingsSelectors.getHotkeyById(HotkeyEnum.OpenChatSettings));
28
22
  const { t } = useTranslation('common');
29
23
  const id = useSessionStore((s) => s.activeId);
30
- const isGroupSession = useSessionStore(sessionSelectors.isCurrentSessionGroupSession);
31
24
 
32
- // The chat settings need some compatibility so we use a hook but for
33
- // the group settings we use a store directly
34
25
  const openChatSettings = useOpenChatSettings();
35
- const openGroupSettings = useAgentGroupStore((s) => s.toggleGroupSetting);
36
26
 
37
27
  return (
38
28
  <>
39
29
  <ActionIcon
40
30
  icon={AlignJustify}
41
- onClick={() => (isGroupSession ? openGroupSettings(true) : openChatSettings())}
31
+ onClick={() => openChatSettings()}
42
32
  size={mobile ? MOBILE_HEADER_ICON_SIZE : DESKTOP_HEADER_ICON_SIZE}
43
33
  title={t('openChatSettings.title', { ns: 'hotkey' })}
44
34
  tooltipProps={{
@@ -47,7 +37,7 @@ const SettingButton = memo<{ mobile?: boolean }>(({ mobile }) => {
47
37
  }}
48
38
  />
49
39
 
50
- {isGroupSession ? <AgentTeamSettings key={id} /> : <AgentSettingsEditor key={id} />}
40
+ <AgentSettingsEditor key={id} />
51
41
  </>
52
42
  );
53
43
  });
@@ -191,15 +191,9 @@ export interface ChatGroupWizardProps {
191
191
  */
192
192
  isCreatingFromTemplate?: boolean;
193
193
  onCancel: () => void;
194
- onCreateCustom: (
195
- selectedAgents: string[],
196
- hostConfig?: { model?: string; provider?: string },
197
- enableSupervisor?: boolean,
198
- ) => void | Promise<void>;
194
+ onCreateCustom: (selectedAgents: string[]) => void | Promise<void>;
199
195
  onCreateFromTemplate: (
200
196
  templateId: string,
201
- hostConfig?: { model?: string; provider?: string },
202
- enableSupervisor?: boolean,
203
197
  selectedMemberTitles?: string[],
204
198
  ) => void | Promise<void>;
205
199
  open: boolean;
@@ -495,8 +489,6 @@ const ChatGroupWizard = memo<ChatGroupWizardProps>(
495
489
  const handleTemplateConfirm = useCallback(async () => {
496
490
  if (!selectedTemplate) return;
497
491
 
498
- const hostConfig = isHostRemoved ? undefined : normalizedHostModelConfig;
499
-
500
492
  try {
501
493
  // collect selected member titles (not removed)
502
494
  const template = groupTemplates.find((t) => t.id === selectedTemplate);
@@ -505,33 +497,19 @@ const ChatGroupWizard = memo<ChatGroupWizardProps>(
505
497
  .filter((m) => m !== null && m !== undefined && !removedForTemplate.has(m.title))
506
498
  .map((m) => m.title);
507
499
 
508
- await onCreateFromTemplate(
509
- selectedTemplate,
510
- hostConfig,
511
- !isHostRemoved,
512
- selectedMemberTitles,
513
- );
500
+ await onCreateFromTemplate(selectedTemplate, selectedMemberTitles);
514
501
  handleReset();
515
502
  } catch (error) {
516
503
  console.error('Failed to create group from template:', error);
517
504
  }
518
- }, [
519
- selectedTemplate,
520
- onCreateFromTemplate,
521
- normalizedHostModelConfig,
522
- isHostRemoved,
523
- groupTemplates,
524
- removedMembers,
525
- ]);
505
+ }, [selectedTemplate, onCreateFromTemplate, groupTemplates, removedMembers]);
526
506
 
527
507
  const handleCustomConfirm = useCallback(async () => {
528
508
  if (selectedAgents.length === 0) return;
529
509
 
530
- const hostConfig = isHostRemoved ? undefined : normalizedHostModelConfig;
531
-
532
510
  try {
533
511
  setIsCreatingCustom(true);
534
- await onCreateCustom(selectedAgents, hostConfig, !isHostRemoved);
512
+ await onCreateCustom(selectedAgents);
535
513
  handleReset();
536
514
  onCancel();
537
515
  } catch (error) {
@@ -539,7 +517,7 @@ const ChatGroupWizard = memo<ChatGroupWizardProps>(
539
517
  } finally {
540
518
  setIsCreatingCustom(false);
541
519
  }
542
- }, [selectedAgents, onCreateCustom, normalizedHostModelConfig, isHostRemoved, onCancel]);
520
+ }, [selectedAgents, onCreateCustom, onCancel]);
543
521
 
544
522
  const handleConfirm = useCallback(async () => {
545
523
  if (selectedTemplate) {