@lobehub/lobehub 2.0.0-next.293 → 2.0.0-next.295

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 (181) hide show
  1. package/.github/workflows/release-desktop-beta.yml +6 -6
  2. package/.github/workflows/release-desktop-stable.yml +11 -11
  3. package/CHANGELOG.md +52 -0
  4. package/apps/desktop/electron.vite.config.ts +0 -1
  5. package/apps/desktop/src/main/__mocks__/node-mac-permissions.ts +0 -1
  6. package/apps/desktop/src/main/__mocks__/setup.ts +0 -1
  7. package/apps/desktop/src/main/controllers/McpCtr.ts +50 -18
  8. package/apps/desktop/src/main/controllers/__tests__/SystemCtr.test.ts +1 -4
  9. package/apps/desktop/src/main/libs/mcp/client.ts +54 -2
  10. package/apps/desktop/tsconfig.json +4 -10
  11. package/changelog/v1.json +14 -0
  12. package/e2e/scripts/setup.ts +45 -32
  13. package/package.json +1 -1
  14. package/packages/database/src/models/__tests__/knowledgeBase.test.ts +1 -1
  15. package/packages/database/src/repositories/knowledge/index.ts +1 -4
  16. package/packages/types/src/discover/assistants.ts +2 -2
  17. package/scripts/migrate-spa-navigation.ts +129 -0
  18. package/src/app/(backend)/api/workflows/memory-user-memory/pipelines/chat-topic/process-topics/route.ts +112 -109
  19. package/src/app/(backend)/api/workflows/memory-user-memory/pipelines/chat-topic/process-user-topics/route.ts +125 -113
  20. package/src/app/(backend)/api/workflows/memory-user-memory/pipelines/chat-topic/process-users/route.ts +74 -65
  21. package/src/app/[variants]/(auth)/auth-error/page.tsx +1 -1
  22. package/src/app/[variants]/(auth)/login/[[...login]]/page.tsx +1 -1
  23. package/src/app/[variants]/(auth)/next-auth/error/AuthErrorPage.tsx +1 -1
  24. package/src/app/[variants]/(auth)/next-auth/signin/AuthSignInBox.tsx +1 -1
  25. package/src/app/[variants]/(auth)/oauth/callback/error/page.tsx +1 -1
  26. package/src/app/[variants]/(auth)/oauth/callback/success/page.tsx +1 -1
  27. package/src/app/[variants]/(auth)/oauth/consent/[uid]/page.tsx +1 -1
  28. package/src/app/[variants]/(auth)/reset-password/layout.tsx +1 -1
  29. package/src/app/[variants]/(auth)/reset-password/page.tsx +2 -2
  30. package/src/app/[variants]/(auth)/signin/layout.tsx +1 -1
  31. package/src/app/[variants]/(auth)/signin/useSignIn.ts +1 -1
  32. package/src/app/[variants]/(auth)/signup/[[...signup]]/BetterAuthSignUpForm.tsx +2 -2
  33. package/src/app/[variants]/(auth)/signup/[[...signup]]/page.tsx +1 -1
  34. package/src/app/[variants]/(auth)/signup/[[...signup]]/useSignUp.tsx +1 -1
  35. package/src/app/[variants]/(auth)/verify-email/layout.tsx +1 -1
  36. package/src/app/[variants]/(auth)/verify-email/page.tsx +2 -2
  37. package/src/app/[variants]/(main)/_layout/index.tsx +1 -1
  38. package/src/app/[variants]/(main)/agent/_layout/AgentIdSync.tsx +12 -1
  39. package/src/app/[variants]/(main)/agent/_layout/Sidebar/Cron/CronTopicGroup.tsx +1 -1
  40. package/src/app/[variants]/(main)/agent/_layout/Sidebar/Header/AddTopicButon.tsx +1 -1
  41. package/src/app/[variants]/(main)/agent/_layout/Sidebar/Header/Nav.tsx +1 -1
  42. package/src/app/[variants]/(main)/agent/_layout/Sidebar/Topic/AllTopicsDrawer/index.tsx +1 -1
  43. package/src/app/[variants]/(main)/agent/_layout/Sidebar/Topic/hooks/useThreadNavigation.ts +1 -1
  44. package/src/app/[variants]/(main)/agent/_layout/Sidebar/Topic/hooks/useTopicNavigation.ts +1 -1
  45. package/src/app/[variants]/(main)/agent/features/TelemetryNotification.tsx +2 -3
  46. package/src/app/[variants]/(main)/community/(detail)/assistant/features/Details/Nav.tsx +9 -9
  47. package/src/app/[variants]/(main)/community/(detail)/assistant/features/Details/Versions/index.tsx +2 -3
  48. package/src/app/[variants]/(main)/community/(detail)/features/MakedownRender.tsx +1 -2
  49. package/src/app/[variants]/(main)/community/(detail)/features/ShareButton.tsx +2 -3
  50. package/src/app/[variants]/(main)/community/(detail)/features/Toc/Heading.tsx +2 -3
  51. package/src/app/[variants]/(main)/community/(detail)/mcp/features/Details/Versions/index.tsx +2 -2
  52. package/src/app/[variants]/(main)/community/(detail)/model/features/Details/Nav.tsx +12 -11
  53. package/src/app/[variants]/(main)/community/(detail)/model/features/Details/Parameter/ParameterItem.tsx +2 -3
  54. package/src/app/[variants]/(main)/community/(detail)/provider/features/Details/Nav.tsx +11 -10
  55. package/src/app/[variants]/(main)/community/(detail)/provider/features/Header.tsx +10 -9
  56. package/src/app/[variants]/(main)/community/(list)/(home)/index.tsx +1 -1
  57. package/src/app/[variants]/(main)/community/(list)/assistant/features/Category/useCategory.tsx +1 -1
  58. package/src/app/[variants]/(main)/community/(list)/features/SortButton/index.tsx +2 -3
  59. package/src/app/[variants]/(main)/community/_layout/Sidebar/Header/Nav.tsx +1 -1
  60. package/src/app/[variants]/(main)/community/features/CreateButton/Inner.tsx +1 -1
  61. package/src/app/[variants]/(main)/community/features/CreateButton/index.tsx +1 -1
  62. package/src/app/[variants]/(main)/community/features/Search.tsx +1 -2
  63. package/src/app/[variants]/(main)/community/features/Title.tsx +5 -5
  64. package/src/app/[variants]/(main)/group/_layout/GroupIdSync.tsx +12 -1
  65. package/src/app/[variants]/(main)/group/_layout/Sidebar/Header/Nav.tsx +1 -1
  66. package/src/app/[variants]/(main)/group/_layout/Sidebar/Topic/AllTopicsDrawer/index.tsx +1 -1
  67. package/src/app/[variants]/(main)/group/_layout/Sidebar/Topic/hooks/useThreadNavigation.ts +1 -1
  68. package/src/app/[variants]/(main)/group/features/Conversation/Header/ShareButton/index.tsx +1 -1
  69. package/src/app/[variants]/(main)/group/features/TelemetryNotification.tsx +2 -3
  70. package/src/app/[variants]/(main)/home/_layout/Body/Agent/AllAgentsDrawer/index.tsx +1 -1
  71. package/src/app/[variants]/(main)/hooks/useActiveTabKey.ts +6 -11
  72. package/src/app/[variants]/(main)/image/NotSupportClient.tsx +4 -3
  73. package/src/app/[variants]/(main)/image/_layout/ConfigPanel/components/ImageUpload.tsx +1 -1
  74. package/src/app/[variants]/(main)/image/_layout/ConfigPanel/components/MultiImagesUpload/ImageManageModal.tsx +1 -1
  75. package/src/app/[variants]/(main)/image/_layout/ConfigPanel/components/MultiImagesUpload/index.tsx +1 -1
  76. package/src/app/[variants]/(main)/memory/(home)/features/RoleTagCloud/index.tsx +1 -1
  77. package/src/app/[variants]/(main)/memory/_layout/Sidebar/Header/Nav.tsx +1 -1
  78. package/src/app/[variants]/(main)/memory/features/SourceLink.tsx +1 -1
  79. package/src/app/[variants]/(main)/page/_layout/Body/AllPagesDrawer/index.tsx +1 -1
  80. package/src/app/[variants]/(main)/settings/about/features/ItemCard.tsx +2 -3
  81. package/src/app/[variants]/(main)/settings/about/features/ItemLink.tsx +2 -3
  82. package/src/app/[variants]/(main)/settings/about/features/Version.tsx +6 -7
  83. package/src/app/[variants]/(main)/settings/features/SettingsContent.tsx +1 -1
  84. package/src/app/[variants]/(main)/settings/features/UpgradeAlert.tsx +4 -4
  85. package/src/app/[variants]/(main)/settings/provider/(list)/Footer.tsx +2 -2
  86. package/src/app/[variants]/(main)/settings/provider/detail/index.tsx +1 -1
  87. package/src/app/[variants]/(main)/settings/provider/detail/ollama/CheckError.tsx +1 -1
  88. package/src/app/[variants]/(main)/settings/provider/features/ProviderConfig/index.tsx +12 -6
  89. package/src/app/[variants]/(main)/settings/security/index.tsx +1 -1
  90. package/src/app/[variants]/(main)/settings/stats/features/overview/ShareButton/ShareModal.tsx +1 -1
  91. package/src/app/[variants]/(main)/settings/stats/features/rankings/AssistantsRank.tsx +1 -1
  92. package/src/app/[variants]/(main)/settings/stats/features/rankings/TopicsRank.tsx +1 -1
  93. package/src/app/[variants]/(mobile)/_layout/index.tsx +1 -1
  94. package/src/app/[variants]/(mobile)/chat/settings/features/AgentInfoDescription/index.tsx +1 -1
  95. package/src/app/[variants]/(mobile)/chat/settings/features/SettingButton.tsx +1 -1
  96. package/src/app/[variants]/(mobile)/router/index.tsx +1 -1
  97. package/src/app/[variants]/page.tsx +1 -1
  98. package/src/app/[variants]/router/index.tsx +1 -1
  99. package/src/components/404/index.tsx +4 -4
  100. package/src/components/Analytics/index.tsx +1 -1
  101. package/src/components/BrandWatermark/index.tsx +4 -4
  102. package/src/components/Branding/ProductLogo/Custom.tsx +1 -1
  103. package/src/components/Error/index.tsx +3 -4
  104. package/src/components/GoBack/index.tsx +2 -2
  105. package/src/components/LabsModal/LabCard.tsx +1 -1
  106. package/src/components/Link.tsx +25 -5
  107. package/src/components/OllamaSetupGuide/index.tsx +5 -4
  108. package/src/components/WebFavicon/index.tsx +1 -1
  109. package/src/components/client/ClientResponsiveContent/index.tsx +1 -1
  110. package/src/components/client/ClientResponsiveLayout.tsx +1 -1
  111. package/src/components/mdx/Image.tsx +1 -1
  112. package/src/components/mdx/Link.tsx +26 -9
  113. package/src/features/AlertBanner/CloudBanner.tsx +2 -3
  114. package/src/features/ChatInput/ActionBar/Model/ControlsForm.tsx +8 -7
  115. package/src/features/ChatInput/ActionBar/Params/Controls.tsx +1 -3
  116. package/src/features/ChatInput/ActionBar/Token/index.tsx +1 -1
  117. package/src/features/ChatInput/Mobile/index.tsx +1 -1
  118. package/src/features/Conversation/ChatItem/components/MessageContent/index.tsx +1 -1
  119. package/src/features/Conversation/Error/OllamaBizError/index.tsx +1 -1
  120. package/src/features/Conversation/Error/OllamaSetupGuide/Desktop.tsx +1 -2
  121. package/src/features/Conversation/Error/index.tsx +1 -1
  122. package/src/features/Conversation/Messages/AssistantGroup/Tool/Actions/Settings.tsx +1 -1
  123. package/src/features/Conversation/Messages/AssistantGroup/Tool/index.tsx +1 -1
  124. package/src/features/Conversation/Messages/AssistantGroup/index.tsx +1 -1
  125. package/src/features/Conversation/Messages/Tool/Tool/index.tsx +1 -1
  126. package/src/features/Conversation/Messages/components/SearchGrounding.tsx +1 -1
  127. package/src/features/DataImporter/Error.tsx +3 -3
  128. package/src/features/DevPanel/CacheViewer/cacheProvider.tsx +2 -1
  129. package/src/features/DevPanel/MetadataViewer/Og.tsx +1 -1
  130. package/src/features/DevPanel/features/FloatPanel.tsx +1 -1
  131. package/src/features/DevPanel/features/Table/TooltipContent.tsx +3 -4
  132. package/src/features/DevPanel/index.tsx +1 -1
  133. package/src/features/EditorCanvas/InlineToolbar.tsx +1 -6
  134. package/src/features/FileViewer/NotSupport/index.tsx +2 -3
  135. package/src/features/Follow/index.tsx +8 -9
  136. package/src/features/LibraryModal/AddFilesToKnowledgeBase/SelectForm.tsx +2 -2
  137. package/src/features/MCP/MCPInstallProgress/InstallError/ErrorDetails.tsx +61 -83
  138. package/src/features/MCP/Scores.tsx +1 -1
  139. package/src/features/MCPPluginDetail/Nav.tsx +8 -8
  140. package/src/features/MCPPluginDetail/Overview/TagList.tsx +1 -1
  141. package/src/features/MobileTabBar/index.tsx +2 -1
  142. package/src/features/OllamaSetupGuide/Desktop.tsx +1 -2
  143. package/src/features/PWAInstall/Install.tsx +1 -1
  144. package/src/features/PWAInstall/index.tsx +1 -1
  145. package/src/features/PluginDevModal/MCPManifestForm/index.tsx +30 -3
  146. package/src/features/PluginStore/McpList/index.tsx +1 -1
  147. package/src/features/PluginStore/PluginList/Detail/Header.tsx +6 -6
  148. package/src/features/PluginsUI/Render/DefaultType/index.tsx +1 -1
  149. package/src/features/Portal/Artifacts/Body/Renderer/index.tsx +1 -1
  150. package/src/features/ResourceManager/components/ChunkDrawer/index.tsx +1 -1
  151. package/src/features/ResourceManager/components/Explorer/ListView/Skeleton.tsx +26 -26
  152. package/src/features/ResourceManager/components/Explorer/ToolBar/BatchActionsDropdown.tsx +147 -149
  153. package/src/features/ResourceManager/index.tsx +1 -1
  154. package/src/features/Setting/Footer.tsx +4 -5
  155. package/src/features/User/UserPanel/PanelContent.tsx +1 -1
  156. package/src/hooks/useActiveTabKey.ts +6 -3
  157. package/src/hooks/useIsSingleMode.test.ts +10 -24
  158. package/src/hooks/useIsSingleMode.ts +4 -2
  159. package/src/hooks/useIsSubSlug.ts +2 -1
  160. package/src/hooks/useQuery.ts +5 -5
  161. package/src/layout/GlobalProvider/AppTheme.tsx +2 -2
  162. package/src/layout/GlobalProvider/StyleRegistry.tsx +1 -1
  163. package/src/layout/GlobalProvider/useUserStateRedirect.ts +13 -25
  164. package/src/libs/mcp/types.ts +31 -0
  165. package/src/libs/next/Image.tsx +13 -0
  166. package/src/libs/next/Link.tsx +13 -0
  167. package/src/libs/next/dynamic.tsx +13 -0
  168. package/src/libs/next/index.ts +22 -0
  169. package/src/libs/next/navigation.ts +22 -0
  170. package/src/libs/router/Link.tsx +30 -0
  171. package/src/libs/router/index.ts +18 -0
  172. package/src/libs/router/navigation.ts +72 -0
  173. package/src/server/modules/AgentRuntime/AgentStateManager.ts +5 -1
  174. package/src/store/chat/slices/portal/selectors.test.ts +5 -15
  175. package/src/store/page/index.ts +1 -1
  176. package/src/store/page/slices/crud/index.ts +1 -1
  177. package/src/store/tool/slices/mcpStore/action.ts +26 -11
  178. package/src/app/[variants]/(main)/hooks/usePathname.ts +0 -10
  179. package/src/app/[variants]/(main)/hooks/useQuery.ts +0 -12
  180. package/src/app/[variants]/(main)/hooks/useRouter.ts +0 -22
  181. package/src/app/[variants]/(main)/hooks/useSearchParams.ts +0 -11
@@ -2,7 +2,6 @@
2
2
 
3
3
  import { ActionIcon } from '@lobehub/ui';
4
4
  import { MessageSquarePlusIcon } from 'lucide-react';
5
- import { usePathname } from 'next/navigation';
6
5
  import { memo } from 'react';
7
6
  import { useTranslation } from 'react-i18next';
8
7
  import { useParams } from 'react-router-dom';
@@ -10,6 +9,7 @@ import urlJoin from 'url-join';
10
9
 
11
10
  import { DESKTOP_HEADER_ICON_SIZE } from '@/const/layoutTokens';
12
11
  import { useQueryRoute } from '@/hooks/useQueryRoute';
12
+ import { usePathname } from '@/libs/router/navigation';
13
13
  import { useActionSWR } from '@/libs/swr';
14
14
  import { useChatStore } from '@/store/chat';
15
15
  import { useUserStore } from '@/store/user';
@@ -3,7 +3,6 @@
3
3
  import { Flexbox } from '@lobehub/ui';
4
4
  import { BotPromptIcon } from '@lobehub/ui/icons';
5
5
  import { MessageSquarePlusIcon, SearchIcon } from 'lucide-react';
6
- import { usePathname } from 'next/navigation';
7
6
  import { memo } from 'react';
8
7
  import { useTranslation } from 'react-i18next';
9
8
  import { useParams } from 'react-router-dom';
@@ -11,6 +10,7 @@ import urlJoin from 'url-join';
11
10
 
12
11
  import NavItem from '@/features/NavPanel/components/NavItem';
13
12
  import { useQueryRoute } from '@/hooks/useQueryRoute';
13
+ import { usePathname } from '@/libs/router/navigation';
14
14
  import { useActionSWR } from '@/libs/swr';
15
15
  import { useAgentStore } from '@/store/agent';
16
16
  import { builtinAgentSelectors } from '@/store/agent/selectors';
@@ -1,12 +1,12 @@
1
1
  'use client';
2
2
 
3
3
  import { Flexbox, SearchBar } from '@lobehub/ui';
4
- import dynamic from 'next/dynamic';
5
4
  import { memo, useState } from 'react';
6
5
  import { useTranslation } from 'react-i18next';
7
6
 
8
7
  import SideBarDrawer from '@/features/NavPanel/SideBarDrawer';
9
8
  import SkeletonList from '@/features/NavPanel/components/SkeletonList';
9
+ import dynamic from '@/libs/next/dynamic';
10
10
 
11
11
  const Content = dynamic(() => import('./Content'), {
12
12
  loading: () => (
@@ -1,9 +1,9 @@
1
- import { usePathname } from 'next/navigation';
2
1
  import { useCallback } from 'react';
3
2
  import { useParams } from 'react-router-dom';
4
3
  import urlJoin from 'url-join';
5
4
 
6
5
  import { useQueryRoute } from '@/hooks/useQueryRoute';
6
+ import { usePathname } from '@/libs/router/navigation';
7
7
  import { useChatStore } from '@/store/chat';
8
8
  import { useGlobalStore } from '@/store/global';
9
9
 
@@ -1,8 +1,8 @@
1
- import { usePathname } from 'next/navigation';
2
1
  import { useCallback } from 'react';
3
2
  import urlJoin from 'url-join';
4
3
 
5
4
  import { useQueryRoute } from '@/hooks/useQueryRoute';
5
+ import { usePathname } from '@/libs/router/navigation';
6
6
  import { useChatStore } from '@/store/chat';
7
7
  import { useGlobalStore } from '@/store/global';
8
8
 
@@ -4,7 +4,6 @@ import { BRANDING_NAME } from '@lobechat/business-const';
4
4
  import { Avatar, Button, Flexbox, Icon } from '@lobehub/ui';
5
5
  import { createStaticStyles, cssVar } from 'antd-style';
6
6
  import { LucideArrowUpRightFromSquare, TelescopeIcon } from 'lucide-react';
7
- import Link from 'next/link';
8
7
  import { memo } from 'react';
9
8
  import { useTranslation } from 'react-i18next';
10
9
 
@@ -56,10 +55,10 @@ const TelemetryNotification = memo<{ mobile?: boolean }>(({ mobile }) => {
56
55
  <div className={styles.desc}>
57
56
  {t('telemetry.desc', { appName: BRANDING_NAME })}
58
57
  <span>
59
- <Link href={PRIVACY_URL} target={'_blank'}>
58
+ <a href={PRIVACY_URL} rel="noreferrer" target="_blank">
60
59
  {t('telemetry.learnMore')}
61
60
  <Icon icon={LucideArrowUpRightFromSquare} style={{ marginInlineStart: 4 }} />
62
- </Link>
61
+ </a>
63
62
  </span>
64
63
  </div>
65
64
  </Flexbox>
@@ -4,7 +4,6 @@ import { SOCIAL_URL } from '@lobechat/business-const';
4
4
  import { Flexbox, Icon, Tabs, Tag } from '@lobehub/ui';
5
5
  import { createStaticStyles } from 'antd-style';
6
6
  import { BookOpenIcon, HistoryIcon, LayersIcon, ListIcon, SquareUserIcon } from 'lucide-react';
7
- import Link from 'next/link';
8
7
  import { memo } from 'react';
9
8
  import { useTranslation } from 'react-i18next';
10
9
  import urlJoin from 'url-join';
@@ -104,21 +103,22 @@ const Nav = memo<NavProps>(({ mobile, setActiveTab, activeTab = AssistantNavKey.
104
103
  <Flexbox align={'center'} className={styles.nav} horizontal justify={'space-between'}>
105
104
  {nav}
106
105
  <Flexbox gap={12} horizontal>
107
- <Link className={styles.link} href={SOCIAL_URL.discord} target={'_blank'}>
106
+ <a className={styles.link} href={SOCIAL_URL.discord} rel="noreferrer" target="_blank">
108
107
  {t('mcp.details.nav.needHelp')}
109
- </Link>
108
+ </a>
110
109
  {identifier && marketplaceLink && (
111
- <Link className={styles.link} href={marketplaceLink} target={'_blank'}>
110
+ <a className={styles.link} href={marketplaceLink} rel="noreferrer" target="_blank">
112
111
  {t('mcp.details.nav.viewSourceCode')}
113
- </Link>
112
+ </a>
114
113
  )}
115
- <Link
114
+ <a
116
115
  className={styles.link}
117
- href={'https://github.com/lobehub/lobe-chat-agents/issues/new/choose'}
118
- target={'_blank'}
116
+ href="https://github.com/lobehub/lobe-chat-agents/issues/new/choose"
117
+ rel="noreferrer"
118
+ target="_blank"
119
119
  >
120
120
  {t('mcp.details.nav.reportIssue')}
121
- </Link>
121
+ </a>
122
122
  </Flexbox>
123
123
  </Flexbox>
124
124
  );
@@ -5,9 +5,8 @@ import qs from 'query-string';
5
5
  import { memo, useMemo } from 'react';
6
6
  import { useTranslation } from 'react-i18next';
7
7
 
8
- import Link from '@/app/[variants]/(main)/components/Link';
9
- import { usePathname } from '@/app/[variants]/(main)/hooks/usePathname';
10
- import { useQuery } from '@/app/[variants]/(main)/hooks/useQuery';
8
+ import Link from '@/libs/router/Link';
9
+ import { usePathname , useQuery } from '@/libs/router/navigation';
11
10
  import InlineTable from '@/components/InlineTable';
12
11
  import PublishedTime from '@/components/PublishedTime';
13
12
  import { type AssistantMarketSource, AssistantNavKey } from '@/types/discover';
@@ -2,7 +2,6 @@
2
2
 
3
3
  import { Center, Empty, Markdown } from '@lobehub/ui';
4
4
  import { FileText } from 'lucide-react';
5
- import Link from 'next/link';
6
5
  import { type ReactNode, memo } from 'react';
7
6
  import { useTranslation } from 'react-i18next';
8
7
 
@@ -28,7 +27,7 @@ const MarkdownRender = memo<{ children?: string }>(({ children }) => {
28
27
  components={{
29
28
  a: ({ href, ...rest }: { children?: ReactNode; href?: string }) => {
30
29
  if (href && href.startsWith('http'))
31
- return <Link {...rest} href={href} target={'_blank'} />;
30
+ return <a {...rest} href={href} rel="noreferrer" target="_blank" />;
32
31
  return rest?.children;
33
32
  },
34
33
  h1: H1,
@@ -15,7 +15,6 @@ import {
15
15
  import { createStaticStyles, cssVar } from 'antd-style';
16
16
  import { startCase } from 'es-toolkit/compat';
17
17
  import { LinkIcon, Share2Icon } from 'lucide-react';
18
- import Link from 'next/link';
19
18
  import { type ReactNode, memo, useState } from 'react';
20
19
  import { useTranslation } from 'react-i18next';
21
20
 
@@ -121,14 +120,14 @@ const ShareButton = memo<ShareButtonProps>(({ meta, ...rest }) => {
121
120
  {[x, reddit, telegram, whatsapp, mastodon, weibo].map(
122
121
  (item) =>
123
122
  item.icon && (
124
- <Link href={item.link} key={item.title} target={'_blank'}>
123
+ <a href={item.link} key={item.title} rel="noreferrer" target="_blank">
125
124
  <ActionIcon
126
125
  className={styles.icon}
127
126
  icon={item.icon}
128
127
  size={{ blockSize: 36, borderRadius: 18, size: 16 }}
129
128
  title={item.title}
130
129
  />
131
- </Link>
130
+ </a>
132
131
  ),
133
132
  )}
134
133
  </Flexbox>
@@ -4,7 +4,6 @@ import { Icon } from '@lobehub/ui';
4
4
  import { createStaticStyles, cssVar, cx } from 'antd-style';
5
5
  import { kebabCase } from 'es-toolkit/compat';
6
6
  import { Heading2, Heading3, Heading4, Heading5 } from 'lucide-react';
7
- import Link from 'next/link';
8
7
  import {
9
8
  Children,
10
9
  type ComponentProps,
@@ -92,14 +91,14 @@ const createHeading = (Tag: `h${1 | 2 | 3 | 4 | 5 | 6}`) => {
92
91
  id={id}
93
92
  >
94
93
  {children}
95
- <Link
94
+ <a
96
95
  aria-label="Permalink for this section"
97
96
  className={styles.anchor}
98
97
  href={`#${id}`}
99
98
  style={{ scrollMarginTop: 96 }}
100
99
  >
101
100
  <Icon icon={HeadingIcon[Tag]} />
102
- </Link>
101
+ </a>
103
102
  </Tag>
104
103
  );
105
104
  };
@@ -5,8 +5,8 @@ import qs from 'query-string';
5
5
  import { memo } from 'react';
6
6
  import { useTranslation } from 'react-i18next';
7
7
 
8
- import Link from '@/app/[variants]/(main)/components/Link';
9
- import { usePathname } from '@/app/[variants]/(main)/hooks/usePathname';
8
+ import Link from '@/libs/router/Link';
9
+ import { usePathname } from '@/libs/router/navigation';
10
10
  import InlineTable from '@/components/InlineTable';
11
11
 
12
12
  import PublishedTime from '../../../../../../../../../components/PublishedTime';
@@ -4,7 +4,6 @@ import { SOCIAL_URL } from '@lobechat/business-const';
4
4
  import { Flexbox, Icon, Tabs } from '@lobehub/ui';
5
5
  import { createStaticStyles } from 'antd-style';
6
6
  import { BookOpenIcon, ListIcon, Settings2Icon } from 'lucide-react';
7
- import Link from 'next/link';
8
7
  import { memo } from 'react';
9
8
  import { useTranslation } from 'react-i18next';
10
9
 
@@ -65,23 +64,25 @@ const Nav = memo<NavProps>(({ mobile, setActiveTab, activeTab = ModelNavKey.Over
65
64
  <Flexbox align={'center'} className={styles.nav} horizontal justify={'space-between'}>
66
65
  {nav}
67
66
  <Flexbox gap={12} horizontal>
68
- <Link className={styles.link} href={SOCIAL_URL.discord} target={'_blank'}>
67
+ <a className={styles.link} href={SOCIAL_URL.discord} rel="noreferrer" target="_blank">
69
68
  {t('mcp.details.nav.needHelp')}
70
- </Link>
71
- <Link
69
+ </a>
70
+ <a
72
71
  className={styles.link}
73
- href={'https://github.com/lobehub/lobe-chat/tree/main/src/config/aiModels'}
74
- target={'_blank'}
72
+ href="https://github.com/lobehub/lobe-chat/tree/main/src/config/aiModels"
73
+ rel="noreferrer"
74
+ target="_blank"
75
75
  >
76
76
  {t('mcp.details.nav.viewSourceCode')}
77
- </Link>
78
- <Link
77
+ </a>
78
+ <a
79
79
  className={styles.link}
80
- href={'https://github.com/lobehub/lobe-chat/issues/new/choose'}
81
- target={'_blank'}
80
+ href="https://github.com/lobehub/lobe-chat/issues/new/choose"
81
+ rel="noreferrer"
82
+ target="_blank"
82
83
  >
83
84
  {t('mcp.details.nav.reportIssue')}
84
- </Link>
85
+ </a>
85
86
  </Flexbox>
86
87
  </Flexbox>
87
88
  );
@@ -1,7 +1,6 @@
1
1
  import { Flexbox } from '@lobehub/ui';
2
2
  import { Divider } from 'antd';
3
3
  import { cssVar } from 'antd-style';
4
- import Link from 'next/link';
5
4
  import { memo } from 'react';
6
5
  import { useTranslation } from 'react-i18next';
7
6
 
@@ -29,9 +28,9 @@ const ParameterItem = memo<ParameterItemProps>(
29
28
  <Flexbox align={'flex-start'} gap={16}>
30
29
  <p style={{ color: cssVar.colorTextSecondary, margin: 0 }}>
31
30
  {desc}{' '}
32
- <Link href={docUrl} target={'_blank'}>
31
+ <a href={docUrl} rel="noreferrer" target="_blank">
33
32
  {t('models.parameterList.docs')}
34
- </Link>
33
+ </a>
35
34
  </p>
36
35
  <Divider dashed style={{ margin: 0 }} />
37
36
  <Flexbox align={'center'} gap={16} horizontal style={{ paddingBottom: 8 }} wrap={'wrap'}>
@@ -4,7 +4,6 @@ import { BRANDING_PROVIDER, SOCIAL_URL } from '@lobechat/business-const';
4
4
  import { Flexbox, Icon, Tabs } from '@lobehub/ui';
5
5
  import { createStaticStyles } from 'antd-style';
6
6
  import { BookOpenIcon, BrainCircuitIcon, ListIcon } from 'lucide-react';
7
- import Link from 'next/link';
8
7
  import { memo } from 'react';
9
8
  import { useTranslation } from 'react-i18next';
10
9
  import urlJoin from 'url-join';
@@ -78,28 +77,30 @@ const Nav = memo<NavProps>(({ mobile, setActiveTab, activeTab = ProviderNavKey.O
78
77
  <Flexbox align={'center'} className={styles.nav} horizontal justify={'space-between'}>
79
78
  {nav}
80
79
  <Flexbox gap={12} horizontal>
81
- <Link className={styles.link} href={SOCIAL_URL.discord} target={'_blank'}>
80
+ <a className={styles.link} href={SOCIAL_URL.discord} rel="noreferrer" target="_blank">
82
81
  {t('mcp.details.nav.needHelp')}
83
- </Link>
82
+ </a>
84
83
  {identifier && (
85
- <Link
84
+ <a
86
85
  className={styles.link}
87
86
  href={urlJoin(
88
87
  'https://github.com/lobehub/lobe-chat/tree/main/src/config/modelProviders',
89
88
  `${identifier}.ts`,
90
89
  )}
91
- target={'_blank'}
90
+ rel="noreferrer"
91
+ target="_blank"
92
92
  >
93
93
  {t('mcp.details.nav.viewSourceCode')}
94
- </Link>
94
+ </a>
95
95
  )}
96
- <Link
96
+ <a
97
97
  className={styles.link}
98
- href={'https://github.com/lobehub/lobe-chat/issues/new/choose'}
99
- target={'_blank'}
98
+ href="https://github.com/lobehub/lobe-chat/issues/new/choose"
99
+ rel="noreferrer"
100
+ target="_blank"
100
101
  >
101
102
  {t('mcp.details.nav.reportIssue')}
102
- </Link>
103
+ </a>
103
104
  </Flexbox>
104
105
  </Flexbox>
105
106
  );
@@ -4,7 +4,6 @@ import { Github, ProviderCombine } from '@lobehub/icons';
4
4
  import { ActionIcon, Flexbox } from '@lobehub/ui';
5
5
  import { cssVar, useResponsive } from 'antd-style';
6
6
  import { GlobeIcon } from 'lucide-react';
7
- import Link from 'next/link';
8
7
  import { memo } from 'react';
9
8
  import { useTranslation } from 'react-i18next';
10
9
  import urlJoin from 'url-join';
@@ -32,9 +31,9 @@ const Header = memo<{ mobile?: boolean }>(({ mobile: isMobile }) => {
32
31
  <ProviderCombine provider={identifier} size={mobile ? 32 : 48} />
33
32
  <Flexbox align={'center'} gap={4} horizontal>
34
33
  {Boolean(url || modelsUrl) ? (
35
- <Link href={url || (modelsUrl as string)} target={'_blank'}>
34
+ <a href={url || (modelsUrl as string)} rel="noreferrer" target="_blank">
36
35
  @{name}
37
- </Link>
36
+ </a>
38
37
  ) : (
39
38
  <span>@{name}</span>
40
39
  )}
@@ -42,25 +41,27 @@ const Header = memo<{ mobile?: boolean }>(({ mobile: isMobile }) => {
42
41
  </Flexbox>
43
42
  <Flexbox align={'center'} horizontal>
44
43
  {Boolean(url || modelsUrl) && (
45
- <Link
44
+ <a
46
45
  href={(url || modelsUrl) as string}
47
46
  onClick={(e) => e.stopPropagation()}
48
- target={'_blank'}
47
+ rel="noreferrer"
48
+ target="_blank"
49
49
  >
50
50
  <ActionIcon color={cssVar.colorTextDescription} icon={GlobeIcon} />
51
- </Link>
51
+ </a>
52
52
  )}
53
53
 
54
- <Link
54
+ <a
55
55
  href={urlJoin(
56
56
  'https://github.com/lobehub/lobe-chat-agents/tree/main/locales',
57
57
  identifier as string,
58
58
  )}
59
59
  onClick={(e) => e.stopPropagation()}
60
- target={'_blank'}
60
+ rel="noreferrer"
61
+ target="_blank"
61
62
  >
62
63
  <ActionIcon fill={cssVar.colorTextDescription} icon={Github} />
63
- </Link>
64
+ </a>
64
65
  </Flexbox>
65
66
  </Flexbox>
66
67
 
@@ -4,7 +4,7 @@ import { memo } from 'react';
4
4
  import { useTranslation } from 'react-i18next';
5
5
 
6
6
  import { useDiscoverStore } from '@/store/discover';
7
- import { McpSorts, AssistantSorts } from '@/types/discover';
7
+ import { AssistantSorts, McpSorts } from '@/types/discover';
8
8
 
9
9
  import Title from '../../components/Title';
10
10
  import AssistantList from '../assistant/features/List';
@@ -2,6 +2,7 @@ import {
2
2
  BadgeDollarSignIcon,
3
3
  BriefcaseIcon,
4
4
  Coffee,
5
+ CompassIcon,
5
6
  DramaIcon,
6
7
  GamepadIcon,
7
8
  GraduationCapIcon,
@@ -14,7 +15,6 @@ import {
14
15
  PencilIcon,
15
16
  PrinterIcon,
16
17
  TerminalSquareIcon,
17
- CompassIcon,
18
18
  } from 'lucide-react';
19
19
  import { useMemo } from 'react';
20
20
  import { useTranslation } from 'react-i18next';
@@ -1,12 +1,11 @@
1
- import { Dropdown, type DropdownMenuItemType, Icon , Button } from '@lobehub/ui';
1
+ import { Button, Dropdown, type DropdownMenuItemType, Icon } from '@lobehub/ui';
2
2
  import { ArrowDownWideNarrow, ChevronDown } from 'lucide-react';
3
3
  import { memo, useMemo } from 'react';
4
4
  import { useTranslation } from 'react-i18next';
5
5
 
6
- import { usePathname } from '@/app/[variants]/(main)/hooks/usePathname';
7
- import { useQuery } from '@/app/[variants]/(main)/hooks/useQuery';
8
6
  import { useQueryRoute } from '@/hooks/useQueryRoute';
9
7
  import { useMarketAuth } from '@/layout/AuthProvider/MarketAuth';
8
+ import { usePathname , useQuery } from '@/libs/router/navigation';
10
9
  import {
11
10
  AssistantSorts,
12
11
  DiscoverTab,
@@ -3,7 +3,7 @@
3
3
  import { Flexbox } from '@lobehub/ui';
4
4
  import { McpIcon, ProviderIcon } from '@lobehub/ui/icons';
5
5
  import { Bot, Brain, ShapesIcon } from 'lucide-react';
6
- import { usePathname } from 'next/navigation';
6
+ import { usePathname } from '@/libs/router/navigation';
7
7
  import { memo, useMemo } from 'react';
8
8
  import { useTranslation } from 'react-i18next';
9
9
  import { Link, useNavigate } from 'react-router-dom';
@@ -1,7 +1,7 @@
1
1
  import { Button, Icon, Tag, Typography } from '@lobehub/ui';
2
2
  import { Divider } from 'antd';
3
3
  import { Github, Settings, Share2 } from 'lucide-react';
4
- import Image from 'next/image';
4
+ import Image from '@/libs/next/Image';
5
5
  import { memo } from 'react';
6
6
  import { useTranslation } from 'react-i18next';
7
7
 
@@ -1,7 +1,7 @@
1
1
  import { ActionIcon, Button, Modal , Skeleton } from '@lobehub/ui';
2
2
  import { useResponsive } from 'antd-style';
3
3
  import { Brush } from 'lucide-react';
4
- import dynamic from 'next/dynamic';
4
+ import dynamic from '@/libs/next/dynamic';
5
5
  import { memo, useState } from 'react';
6
6
  import { useTranslation } from 'react-i18next';
7
7
 
@@ -6,8 +6,7 @@ import { memo, useState } from 'react';
6
6
  import { useTranslation } from 'react-i18next';
7
7
  import urlJoin from 'url-join';
8
8
 
9
- import { usePathname } from '@/app/[variants]/(main)/hooks/usePathname';
10
- import { useQuery } from '@/app/[variants]/(main)/hooks/useQuery';
9
+ import { usePathname , useQuery } from '@/libs/router/navigation';
11
10
  import { withSuspense } from '@/components/withSuspense';
12
11
  import { useQueryRoute } from '@/hooks/useQueryRoute';
13
12
 
@@ -3,7 +3,6 @@
3
3
  import { Flexbox, type FlexboxProps, Icon } from '@lobehub/ui';
4
4
  import { createStaticStyles, cx } from 'antd-style';
5
5
  import { ChevronRight } from 'lucide-react';
6
- import NextLink from 'next/link';
7
6
  import { type ReactNode, memo } from 'react';
8
7
  import { Link as RouterLink } from 'react-router-dom';
9
8
 
@@ -51,10 +50,10 @@ const Title = memo<TitleProps>(
51
50
  if (moreLink) {
52
51
  if (isExternalLink) {
53
52
  moreLinkElement = (
54
- <NextLink className={styles.more} href={moreLink} target="_blank">
53
+ <a className={styles.more} href={moreLink} rel="noreferrer" target="_blank">
55
54
  <span style={{ marginRight: 4 }}>{more}</span>
56
55
  <Icon icon={ChevronRight} />
57
- </NextLink>
56
+ </a>
58
57
  );
59
58
  } else if (isCommunityRoute) {
60
59
  moreLinkElement = (
@@ -64,11 +63,12 @@ const Title = memo<TitleProps>(
64
63
  </RouterLink>
65
64
  );
66
65
  } else {
66
+ // For non-external, non-community routes (like auth pages), use RouterLink
67
67
  moreLinkElement = (
68
- <NextLink className={styles.more} href={moreLink}>
68
+ <RouterLink className={styles.more} to={moreLink}>
69
69
  <span style={{ marginRight: 4 }}>{more}</span>
70
70
  <Icon icon={ChevronRight} />
71
- </NextLink>
71
+ </RouterLink>
72
72
  );
73
73
  }
74
74
  }
@@ -1,4 +1,5 @@
1
- import { useUnmount } from 'ahooks';
1
+ import { usePrevious, useUnmount } from 'ahooks';
2
+ import { useEffect } from 'react';
2
3
  import { useParams } from 'react-router-dom';
3
4
  import { createStoreUpdater } from 'zustand-utils';
4
5
 
@@ -10,6 +11,7 @@ const GroupIdSync = () => {
10
11
  const useAgentGroupStoreUpdater = createStoreUpdater(useAgentGroupStore);
11
12
  const useChatStoreUpdater = createStoreUpdater(useChatStore);
12
13
  const params = useParams<{ gid?: string }>();
14
+ const prevGroupId = usePrevious(params.gid);
13
15
  const router = useQueryRoute();
14
16
 
15
17
  // Sync groupId to agentGroupStore and chatStore
@@ -19,6 +21,15 @@ const GroupIdSync = () => {
19
21
  // Inject router to agentGroupStore for navigation
20
22
  useAgentGroupStoreUpdater('router', router);
21
23
 
24
+ // Reset activeTopicId when switching to a different group
25
+ // This prevents messages from being saved to the wrong topic bucket
26
+ useEffect(() => {
27
+ // Only reset topic when switching between groups (not on initial mount)
28
+ if (prevGroupId !== undefined && prevGroupId !== params.gid) {
29
+ useChatStore.getState().switchTopic(null, { skipRefreshMessage: true });
30
+ }
31
+ }, [params.gid, prevGroupId]);
32
+
22
33
  // Clear activeGroupId when unmounting (leaving group page)
23
34
  useUnmount(() => {
24
35
  useAgentGroupStore.setState({ activeGroupId: undefined, router: undefined });
@@ -3,7 +3,6 @@
3
3
  import { Flexbox } from '@lobehub/ui';
4
4
  import { BotPromptIcon } from '@lobehub/ui/icons';
5
5
  import { MessageSquarePlusIcon, SearchIcon } from 'lucide-react';
6
- import { usePathname } from 'next/navigation';
7
6
  import { memo } from 'react';
8
7
  import { useTranslation } from 'react-i18next';
9
8
  import { useParams } from 'react-router-dom';
@@ -11,6 +10,7 @@ import urlJoin from 'url-join';
11
10
 
12
11
  import NavItem from '@/features/NavPanel/components/NavItem';
13
12
  import { useQueryRoute } from '@/hooks/useQueryRoute';
13
+ import { usePathname } from '@/libs/router/navigation';
14
14
  import { useAgentGroupStore } from '@/store/agentGroup';
15
15
  import { useChatStore } from '@/store/chat';
16
16
  import { useGlobalStore } from '@/store/global';
@@ -1,7 +1,7 @@
1
1
  'use client';
2
2
 
3
3
  import { Flexbox, SearchBar } from '@lobehub/ui';
4
- import dynamic from 'next/dynamic';
4
+ import dynamic from '@/libs/next/dynamic';
5
5
  import { memo, useState } from 'react';
6
6
  import { useTranslation } from 'react-i18next';
7
7
 
@@ -1,4 +1,4 @@
1
- import { usePathname } from 'next/navigation';
1
+ import { usePathname } from '@/libs/router/navigation';
2
2
  import { useCallback } from 'react';
3
3
  import { useParams } from 'react-router-dom';
4
4
  import urlJoin from 'url-join';
@@ -2,12 +2,12 @@
2
2
 
3
3
  import { ActionIcon } from '@lobehub/ui';
4
4
  import { Share2 } from 'lucide-react';
5
- import dynamic from 'next/dynamic';
6
5
  import { memo } from 'react';
7
6
  import { useTranslation } from 'react-i18next';
8
7
 
9
8
  import { DESKTOP_HEADER_ICON_SIZE, MOBILE_HEADER_ICON_SIZE } from '@/const/layoutTokens';
10
9
  import { useWorkspaceModal } from '@/hooks/useWorkspaceModal';
10
+ import dynamic from '@/libs/next/dynamic';
11
11
  import { useChatStore } from '@/store/chat';
12
12
  import { useServerConfigStore } from '@/store/serverConfig';
13
13
  import { serverConfigSelectors } from '@/store/serverConfig/selectors';
@@ -4,7 +4,6 @@ import { BRANDING_NAME } from '@lobechat/business-const';
4
4
  import { Avatar, Button, Flexbox, Icon } from '@lobehub/ui';
5
5
  import { createStaticStyles, cssVar } from 'antd-style';
6
6
  import { LucideArrowUpRightFromSquare, TelescopeIcon } from 'lucide-react';
7
- import Link from 'next/link';
8
7
  import { memo } from 'react';
9
8
  import { useTranslation } from 'react-i18next';
10
9
 
@@ -56,10 +55,10 @@ const TelemetryNotification = memo<{ mobile?: boolean }>(({ mobile }) => {
56
55
  <div className={styles.desc}>
57
56
  {t('telemetry.desc', { appName: BRANDING_NAME })}
58
57
  <span>
59
- <Link href={PRIVACY_URL} target={'_blank'}>
58
+ <a href={PRIVACY_URL} rel="noreferrer" target="_blank">
60
59
  {t('telemetry.learnMore')}
61
60
  <Icon icon={LucideArrowUpRightFromSquare} style={{ marginInlineStart: 4 }} />
62
- </Link>
61
+ </a>
63
62
  </span>
64
63
  </div>
65
64
  </Flexbox>
@@ -1,7 +1,7 @@
1
1
  'use client';
2
2
 
3
3
  import { Flexbox, SearchBar } from '@lobehub/ui';
4
- import dynamic from 'next/dynamic';
4
+ import dynamic from '@/libs/next/dynamic';
5
5
  import { memo, useState } from 'react';
6
6
  import { useTranslation } from 'react-i18next';
7
7