@lobehub/chat 1.18.1 → 1.19.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of @lobehub/chat might be problematic. Click here for more details.

Files changed (181) hide show
  1. package/CHANGELOG.md +52 -0
  2. package/Dockerfile +2 -0
  3. package/Dockerfile.database +2 -0
  4. package/locales/ar/chat.json +6 -0
  5. package/locales/ar/error.json +1 -0
  6. package/locales/ar/modelProvider.json +7 -0
  7. package/locales/ar/portal.json +16 -0
  8. package/locales/bg-BG/chat.json +6 -0
  9. package/locales/bg-BG/error.json +1 -0
  10. package/locales/bg-BG/modelProvider.json +7 -0
  11. package/locales/bg-BG/portal.json +16 -0
  12. package/locales/de-DE/chat.json +6 -0
  13. package/locales/de-DE/error.json +1 -0
  14. package/locales/de-DE/modelProvider.json +7 -0
  15. package/locales/de-DE/portal.json +16 -0
  16. package/locales/en-US/chat.json +6 -0
  17. package/locales/en-US/error.json +1 -0
  18. package/locales/en-US/modelProvider.json +7 -0
  19. package/locales/en-US/portal.json +16 -0
  20. package/locales/es-ES/chat.json +6 -0
  21. package/locales/es-ES/error.json +1 -0
  22. package/locales/es-ES/modelProvider.json +7 -0
  23. package/locales/es-ES/portal.json +16 -0
  24. package/locales/fr-FR/chat.json +6 -0
  25. package/locales/fr-FR/error.json +1 -0
  26. package/locales/fr-FR/modelProvider.json +7 -0
  27. package/locales/fr-FR/portal.json +16 -0
  28. package/locales/it-IT/chat.json +6 -0
  29. package/locales/it-IT/error.json +1 -0
  30. package/locales/it-IT/modelProvider.json +7 -0
  31. package/locales/it-IT/portal.json +16 -0
  32. package/locales/ja-JP/chat.json +6 -0
  33. package/locales/ja-JP/error.json +1 -0
  34. package/locales/ja-JP/modelProvider.json +7 -0
  35. package/locales/ja-JP/portal.json +16 -0
  36. package/locales/ko-KR/chat.json +6 -0
  37. package/locales/ko-KR/error.json +1 -0
  38. package/locales/ko-KR/modelProvider.json +7 -0
  39. package/locales/ko-KR/portal.json +16 -0
  40. package/locales/nl-NL/chat.json +6 -0
  41. package/locales/nl-NL/error.json +1 -0
  42. package/locales/nl-NL/modelProvider.json +7 -0
  43. package/locales/nl-NL/portal.json +16 -0
  44. package/locales/pl-PL/chat.json +6 -0
  45. package/locales/pl-PL/error.json +1 -0
  46. package/locales/pl-PL/modelProvider.json +7 -0
  47. package/locales/pl-PL/portal.json +16 -0
  48. package/locales/pt-BR/chat.json +6 -0
  49. package/locales/pt-BR/error.json +1 -0
  50. package/locales/pt-BR/modelProvider.json +7 -0
  51. package/locales/pt-BR/portal.json +16 -0
  52. package/locales/ru-RU/chat.json +6 -0
  53. package/locales/ru-RU/error.json +1 -0
  54. package/locales/ru-RU/modelProvider.json +7 -0
  55. package/locales/ru-RU/portal.json +16 -0
  56. package/locales/tr-TR/chat.json +6 -0
  57. package/locales/tr-TR/error.json +1 -0
  58. package/locales/tr-TR/modelProvider.json +7 -0
  59. package/locales/tr-TR/portal.json +16 -0
  60. package/locales/vi-VN/chat.json +6 -0
  61. package/locales/vi-VN/error.json +1 -0
  62. package/locales/vi-VN/modelProvider.json +7 -0
  63. package/locales/vi-VN/portal.json +16 -0
  64. package/locales/zh-CN/chat.json +6 -0
  65. package/locales/zh-CN/error.json +2 -1
  66. package/locales/zh-CN/modelProvider.json +7 -0
  67. package/locales/zh-CN/portal.json +17 -1
  68. package/locales/zh-TW/chat.json +6 -0
  69. package/locales/zh-TW/error.json +1 -0
  70. package/locales/zh-TW/modelProvider.json +7 -0
  71. package/locales/zh-TW/portal.json +16 -0
  72. package/package.json +4 -1
  73. package/src/app/(main)/chat/(workspace)/@portal/Artifacts/Body/Renderer/HTML.tsx +25 -0
  74. package/src/app/(main)/chat/(workspace)/@portal/Artifacts/Body/Renderer/React.tsx +30 -0
  75. package/src/app/(main)/chat/(workspace)/@portal/Artifacts/Body/Renderer/SVG.tsx +114 -0
  76. package/src/app/(main)/chat/(workspace)/@portal/Artifacts/Body/Renderer/index.tsx +25 -0
  77. package/src/app/(main)/chat/(workspace)/@portal/Artifacts/Body/index.tsx +79 -0
  78. package/src/app/(main)/chat/(workspace)/@portal/Artifacts/Header.tsx +69 -0
  79. package/src/app/(main)/chat/(workspace)/@portal/Artifacts/index.ts +10 -0
  80. package/src/app/(main)/chat/(workspace)/@portal/Artifacts/useEnable.ts +4 -0
  81. package/src/app/(main)/chat/(workspace)/@portal/FilePreview/index.ts +2 -1
  82. package/src/app/(main)/chat/(workspace)/@portal/Home/Body/{Artifacts → Plugins}/index.tsx +1 -1
  83. package/src/app/(main)/chat/(workspace)/@portal/Home/Body/index.tsx +2 -2
  84. package/src/app/(main)/chat/(workspace)/@portal/MessageDetail/index.ts +2 -1
  85. package/src/app/(main)/chat/(workspace)/@portal/Plugins/Body/ToolRender.tsx +1 -1
  86. package/src/app/(main)/chat/(workspace)/@portal/Plugins/Body/index.tsx +1 -1
  87. package/src/app/(main)/chat/(workspace)/@portal/Plugins/Footer.tsx +1 -1
  88. package/src/app/(main)/chat/(workspace)/@portal/Plugins/index.ts +2 -1
  89. package/src/app/(main)/chat/(workspace)/@portal/Plugins/useEnable.ts +1 -1
  90. package/src/app/(main)/chat/(workspace)/@portal/_layout/Desktop.tsx +2 -4
  91. package/src/app/(main)/chat/(workspace)/@portal/features/Body.tsx +27 -0
  92. package/src/app/(main)/chat/(workspace)/@portal/router.tsx +3 -1
  93. package/src/app/(main)/chat/(workspace)/@portal/type.ts +7 -0
  94. package/src/app/(main)/chat/(workspace)/_layout/Desktop/Portal.tsx +3 -2
  95. package/src/app/(main)/discover/(detail)/assistant/[slug]/features/InfoSidebar/index.tsx +5 -8
  96. package/src/app/(main)/discover/(detail)/features/Back.tsx +0 -5
  97. package/src/app/(main)/discover/(detail)/features/DetailLayout.tsx +2 -34
  98. package/src/app/(main)/discover/(detail)/model/[...slugs]/features/InfoSidebar/index.tsx +3 -6
  99. package/src/app/(main)/discover/(detail)/model/[...slugs]/features/ProviderList/ProviderItem.tsx +14 -15
  100. package/src/app/(main)/discover/(detail)/plugin/[slug]/features/InfoSidebar/index.tsx +3 -6
  101. package/src/app/(main)/discover/(detail)/provider/[slug]/features/InfoSidebar/index.tsx +3 -6
  102. package/src/app/(main)/discover/(detail)/provider/[slug]/features/ModelList/ModelItem.tsx +14 -11
  103. package/src/app/(main)/discover/(list)/(home)/features/AssistantList.tsx +5 -11
  104. package/src/app/(main)/discover/(list)/(home)/features/ModelList.tsx +3 -3
  105. package/src/app/(main)/discover/(list)/(home)/features/PluginList.tsx +3 -6
  106. package/src/app/(main)/discover/(list)/assistants/features/List.tsx +7 -16
  107. package/src/app/(main)/discover/(list)/models/features/List.tsx +5 -11
  108. package/src/app/(main)/discover/(list)/plugins/features/List.tsx +7 -16
  109. package/src/app/(main)/discover/(list)/providers/features/List.tsx +5 -11
  110. package/src/app/(main)/discover/_layout/Desktop/index.tsx +3 -0
  111. package/src/app/(main)/discover/_layout/Mobile/index.tsx +8 -1
  112. package/src/app/(main)/settings/llm/ProviderList/Github/index.tsx +53 -0
  113. package/src/app/(main)/settings/llm/ProviderList/providers.tsx +6 -1
  114. package/src/app/api/chat/agentRuntime.ts +14 -0
  115. package/src/app/layout.tsx +2 -1
  116. package/src/components/NProgress/index.tsx +12 -0
  117. package/src/components/SidebarHeader/index.tsx +1 -1
  118. package/src/config/llm.ts +14 -0
  119. package/src/config/modelProviders/ai21.ts +37 -0
  120. package/src/config/modelProviders/anthropic.ts +4 -0
  121. package/src/config/modelProviders/github.ts +209 -0
  122. package/src/config/modelProviders/index.ts +8 -0
  123. package/src/const/layoutTokens.ts +1 -1
  124. package/src/const/plugin.test.ts +80 -0
  125. package/src/const/plugin.ts +12 -0
  126. package/src/const/settings/llm.ts +10 -0
  127. package/src/features/Conversation/Error/APIKeyForm/index.tsx +4 -0
  128. package/src/features/Conversation/Messages/Tool/Inspector/index.tsx +1 -1
  129. package/src/features/Conversation/Messages/Tool/index.tsx +1 -1
  130. package/src/features/Conversation/components/ChatItem/index.tsx +24 -2
  131. package/src/features/Conversation/components/ChatItem/utils.test.ts +150 -0
  132. package/src/features/Conversation/components/ChatItem/utils.ts +28 -0
  133. package/src/features/Conversation/components/InboxWelcome/AgentsSuggest.tsx +3 -6
  134. package/src/features/Conversation/components/MarkdownElements/LobeArtifact/Render/Icon.tsx +96 -0
  135. package/src/features/Conversation/components/MarkdownElements/LobeArtifact/Render/index.tsx +129 -0
  136. package/src/features/Conversation/components/MarkdownElements/LobeArtifact/index.ts +10 -0
  137. package/src/features/Conversation/components/MarkdownElements/LobeArtifact/rehypePlugin.ts +74 -0
  138. package/src/features/Conversation/components/MarkdownElements/LobeThinking/Render.tsx +86 -0
  139. package/src/features/Conversation/components/MarkdownElements/LobeThinking/index.ts +12 -0
  140. package/src/features/Conversation/components/MarkdownElements/LobeThinking/rehypePlugin.test.ts +124 -0
  141. package/src/features/Conversation/components/MarkdownElements/LobeThinking/rehypePlugin.ts +51 -0
  142. package/src/features/Conversation/components/MarkdownElements/index.ts +4 -0
  143. package/src/features/Conversation/components/MarkdownElements/type.ts +7 -0
  144. package/src/hooks/useInterceptingRoutes.ts +1 -16
  145. package/src/libs/agent-runtime/AgentRuntime.ts +14 -0
  146. package/src/libs/agent-runtime/ai21/index.test.ts +255 -0
  147. package/src/libs/agent-runtime/ai21/index.ts +18 -0
  148. package/src/libs/agent-runtime/error.ts +2 -0
  149. package/src/libs/agent-runtime/github/index.test.ts +246 -0
  150. package/src/libs/agent-runtime/github/index.ts +15 -0
  151. package/src/libs/agent-runtime/openrouter/__snapshots__/index.test.ts.snap +2215 -28
  152. package/src/libs/agent-runtime/openrouter/fixtures/models.json +3345 -37
  153. package/src/libs/agent-runtime/openrouter/index.ts +2 -1
  154. package/src/libs/agent-runtime/types/type.ts +2 -0
  155. package/src/locales/default/chat.ts +7 -0
  156. package/src/locales/default/error.ts +3 -0
  157. package/src/locales/default/modelProvider.ts +7 -0
  158. package/src/locales/default/portal.ts +17 -1
  159. package/src/server/globalConfig/index.ts +14 -0
  160. package/src/store/chat/slices/message/selectors.ts +30 -28
  161. package/src/store/chat/slices/portal/action.ts +15 -2
  162. package/src/store/chat/slices/portal/initialState.ts +11 -0
  163. package/src/store/chat/slices/portal/selectors.test.ts +29 -7
  164. package/src/store/chat/slices/portal/selectors.ts +56 -12
  165. package/src/styles/loading.ts +28 -0
  166. package/src/tools/artifacts/index.ts +13 -0
  167. package/src/tools/artifacts/systemRole.ts +338 -0
  168. package/src/tools/index.ts +6 -0
  169. package/src/types/user/settings/keyVaults.ts +2 -0
  170. package/src/utils/clipboard.ts +53 -0
  171. package/src/app/@modal/(.)discover/assistant/[slug]/page.tsx +0 -1
  172. package/src/app/@modal/(.)discover/layout.tsx +0 -29
  173. package/src/app/@modal/(.)discover/loading.tsx +0 -3
  174. package/src/app/@modal/(.)discover/model/[...slugs]/page.tsx +0 -1
  175. package/src/app/@modal/(.)discover/plugin/[slug]/page.tsx +0 -1
  176. package/src/app/@modal/(.)discover/provider/[slug]/page.tsx +0 -1
  177. package/src/app/redirect/page.tsx +0 -15
  178. package/src/components/InterceptingLink/index.tsx +0 -27
  179. /package/src/app/(main)/chat/(workspace)/@portal/Home/Body/{Artifacts → Plugins}/ArtifactList/Item/index.tsx +0 -0
  180. /package/src/app/(main)/chat/(workspace)/@portal/Home/Body/{Artifacts → Plugins}/ArtifactList/Item/style.ts +0 -0
  181. /package/src/app/(main)/chat/(workspace)/@portal/Home/Body/{Artifacts → Plugins}/ArtifactList/index.tsx +0 -0
@@ -5,7 +5,6 @@ import { ReactNode, memo } from 'react';
5
5
  import { Flexbox } from 'react-layout-kit';
6
6
 
7
7
  import Footer from '@/features/Setting/Footer';
8
- import { useInterceptingRoutes } from '@/hooks/useInterceptingRoutes';
9
8
 
10
9
  import SidebarContainer from './SidebarContainer';
11
10
 
@@ -20,10 +19,9 @@ interface DetailLayoutProps {
20
19
 
21
20
  const DetailLayout = memo<DetailLayoutProps>(
22
21
  ({ statistics, mobile, header, sidebar, children, actions }) => {
23
- const { md = true, xl = true } = useResponsive();
24
- const { isIntercepted } = useInterceptingRoutes();
22
+ const { md = true } = useResponsive();
25
23
 
26
- if (mobile || !md || (isIntercepted && !xl))
24
+ if (mobile || !md)
27
25
  return (
28
26
  <>
29
27
  {header}
@@ -37,36 +35,6 @@ const DetailLayout = memo<DetailLayoutProps>(
37
35
  </>
38
36
  );
39
37
 
40
- if (isIntercepted) {
41
- return (
42
- <>
43
- <Flexbox flex={1} gap={24} style={{ overflow: 'hidden', position: 'relative' }}>
44
- <Flexbox style={{ paddingRight: 16 }}>{header}</Flexbox>
45
- <Flexbox
46
- gap={24}
47
- style={{
48
- overflowX: 'hidden',
49
- overflowY: 'auto',
50
- paddingBottom: 48,
51
- paddingRight: 16,
52
- position: 'relative',
53
- }}
54
- >
55
- {children}
56
- <Footer />
57
- </Flexbox>
58
- </Flexbox>
59
- <SidebarContainer style={{ position: 'sticky', top: '0' }}>
60
- <Flexbox gap={16} width={'100%'}>
61
- {actions}
62
- {statistics}
63
- </Flexbox>
64
- {sidebar}
65
- </SidebarContainer>
66
- </>
67
- );
68
- }
69
-
70
38
  return (
71
39
  <>
72
40
  {header}
@@ -1,12 +1,12 @@
1
1
  'use client';
2
2
 
3
3
  import { Skeleton } from 'antd';
4
+ import Link from 'next/link';
4
5
  import { memo } from 'react';
5
6
  import { useTranslation } from 'react-i18next';
6
7
  import { Flexbox, FlexboxProps } from 'react-layout-kit';
7
8
  import urlJoin from 'url-join';
8
9
 
9
- import InterceptingLink from '@/components/InterceptingLink';
10
10
  import { DiscoverModelItem } from '@/types/discover';
11
11
 
12
12
  import Block from '../../../../features/Block';
@@ -31,12 +31,9 @@ const InfoSidebar = memo<InfoSidebarProps>(({ data, ...rest }) => {
31
31
  >
32
32
  {data?.suggestions?.length > 0 ? (
33
33
  data?.suggestions.map((item) => (
34
- <InterceptingLink
35
- href={urlJoin('/discover/model', item.identifier)}
36
- key={item.identifier}
37
- >
34
+ <Link href={urlJoin('/discover/model', item.identifier)} key={item.identifier}>
38
35
  <SuggestionItem {...item} />
39
- </InterceptingLink>
36
+ </Link>
40
37
  ))
41
38
  ) : (
42
39
  <Skeleton active paragraph={{ rows: 5 }} title={false} />
@@ -1,7 +1,7 @@
1
1
  import { ModelTag, ProviderCombine } from '@lobehub/icons';
2
2
  import { ActionIcon, Grid, Icon, Tooltip } from '@lobehub/ui';
3
3
  import { Tag } from 'antd';
4
- import { createStyles } from 'antd-style';
4
+ import { createStyles, useResponsive } from 'antd-style';
5
5
  import { BadgeCheck, BookIcon, ChevronRightIcon, KeyIcon } from 'lucide-react';
6
6
  import Link from 'next/link';
7
7
  import { memo, useMemo } from 'react';
@@ -9,7 +9,6 @@ import { useTranslation } from 'react-i18next';
9
9
  import { Flexbox } from 'react-layout-kit';
10
10
  import urlJoin from 'url-join';
11
11
 
12
- import InterceptingLink from '@/components/InterceptingLink';
13
12
  import { DEFAULT_MODEL_PROVIDER_LIST } from '@/config/modelProviders';
14
13
  import { BASE_PROVIDER_DOC_URL } from '@/const/url';
15
14
  import { DiscoverProviderItem } from '@/types/discover';
@@ -31,9 +30,12 @@ interface ProviderItemProps extends DiscoverProviderItem {
31
30
 
32
31
  const ProviderItem = memo<ProviderItemProps>(({ mobile, modelId, identifier }) => {
33
32
  const { t } = useTranslation('discover');
33
+ const { xl = true } = useResponsive();
34
34
  const { styles, theme } = useStyles();
35
35
  const isLobeHub = identifier === 'lobehub';
36
36
 
37
+ const isMobile = mobile || !xl;
38
+
37
39
  const model = useMemo(() => {
38
40
  const prividerItem = DEFAULT_MODEL_PROVIDER_LIST.find((v) => v.id === identifier);
39
41
  if (!prividerItem) return;
@@ -70,13 +72,10 @@ const ProviderItem = memo<ProviderItemProps>(({ mobile, modelId, identifier }) =
70
72
 
71
73
  const header = (
72
74
  <Flexbox gap={4} style={{ minWidth: 240 }}>
73
- <InterceptingLink
74
- href={urlJoin('/discover/provider', identifier)}
75
- style={{ color: 'inherit' }}
76
- >
75
+ <Link href={urlJoin('/discover/provider', identifier)} style={{ color: 'inherit' }}>
77
76
  <ProviderCombine provider={identifier} size={24} />
78
- </InterceptingLink>
79
- <Flexbox align={'center'} gap={6} horizontal>
77
+ </Link>
78
+ <Flexbox align={'center'} gap={6} horizontal wrap={'wrap'}>
80
79
  <ModelTag model={modelId} style={{ background: theme.colorFillQuaternary, margin: 0 }} />
81
80
  {isLobeHub && (
82
81
  <Tooltip title={t('models.providerInfo.officialTooltip')}>
@@ -103,9 +102,9 @@ const ProviderItem = memo<ProviderItemProps>(({ mobile, modelId, identifier }) =
103
102
  );
104
103
 
105
104
  const button = (
106
- <InterceptingLink href={urlJoin('/discover/provider', identifier)} style={{ color: 'inherit' }}>
105
+ <Link href={urlJoin('/discover/provider', identifier)} style={{ color: 'inherit' }}>
107
106
  <ActionIcon color={theme.colorTextDescription} icon={ChevronRightIcon} />
108
- </InterceptingLink>
107
+ </Link>
109
108
  );
110
109
 
111
110
  return (
@@ -117,7 +116,7 @@ const ProviderItem = memo<ProviderItemProps>(({ mobile, modelId, identifier }) =
117
116
  padding={16}
118
117
  wrap={'wrap'}
119
118
  >
120
- {mobile && (
119
+ {isMobile && (
121
120
  <Flexbox align={'center'} horizontal justify={'space-between'}>
122
121
  {header}
123
122
  {button}
@@ -129,13 +128,13 @@ const ProviderItem = memo<ProviderItemProps>(({ mobile, modelId, identifier }) =
129
128
  gap={16}
130
129
  horizontal
131
130
  maxItemWidth={100}
132
- rows={mobile ? 2 : items.length + 1}
131
+ rows={isMobile ? 2 : items.length + 1}
133
132
  style={{ minWidth: 240 }}
134
133
  >
135
- {!mobile && header}
134
+ {!isMobile && header}
136
135
  {items.map((item, index) => (
137
136
  <Statistic
138
- align={mobile ? 'flex-start' : 'center'}
137
+ align={isMobile ? 'flex-start' : 'center'}
139
138
  gap={4}
140
139
  key={index}
141
140
  valuePlacement={'bottom'}
@@ -144,7 +143,7 @@ const ProviderItem = memo<ProviderItemProps>(({ mobile, modelId, identifier }) =
144
143
  />
145
144
  ))}
146
145
  </Grid>
147
- {!mobile && button}
146
+ {!isMobile && button}
148
147
  </Flexbox>
149
148
  );
150
149
  });
@@ -1,12 +1,12 @@
1
1
  'use client';
2
2
 
3
3
  import { Skeleton } from 'antd';
4
+ import Link from 'next/link';
4
5
  import { memo } from 'react';
5
6
  import { useTranslation } from 'react-i18next';
6
7
  import { Flexbox, FlexboxProps } from 'react-layout-kit';
7
8
  import urlJoin from 'url-join';
8
9
 
9
- import InterceptingLink from '@/components/InterceptingLink';
10
10
  import { DiscoverPlugintem } from '@/types/discover';
11
11
 
12
12
  import Block from '../../../../features/Block';
@@ -31,12 +31,9 @@ const InfoSidebar = memo<InfoSidebarProps>(({ data, ...rest }) => {
31
31
  >
32
32
  {data?.suggestions?.length > 0 ? (
33
33
  data?.suggestions.map((item) => (
34
- <InterceptingLink
35
- href={urlJoin('/discover/plugin', item.identifier)}
36
- key={item.identifier}
37
- >
34
+ <Link href={urlJoin('/discover/plugin', item.identifier)} key={item.identifier}>
38
35
  <SuggestionItem {...item} />
39
- </InterceptingLink>
36
+ </Link>
40
37
  ))
41
38
  ) : (
42
39
  <Skeleton active paragraph={{ rows: 5 }} title={false} />
@@ -1,12 +1,12 @@
1
1
  'use client';
2
2
 
3
3
  import { Skeleton } from 'antd';
4
+ import Link from 'next/link';
4
5
  import { memo } from 'react';
5
6
  import { useTranslation } from 'react-i18next';
6
7
  import { Flexbox, FlexboxProps } from 'react-layout-kit';
7
8
  import urlJoin from 'url-join';
8
9
 
9
- import InterceptingLink from '@/components/InterceptingLink';
10
10
  import { DiscoverProviderItem } from '@/types/discover';
11
11
 
12
12
  import Block from '../../../../features/Block';
@@ -31,12 +31,9 @@ const InfoSidebar = memo<InfoSidebarProps>(({ data, ...rest }) => {
31
31
  >
32
32
  {data?.suggestions?.length > 0 ? (
33
33
  data?.suggestions.map((item) => (
34
- <InterceptingLink
35
- href={urlJoin('/discover/provider', item.identifier)}
36
- key={item.identifier}
37
- >
34
+ <Link href={urlJoin('/discover/provider', item.identifier)} key={item.identifier}>
38
35
  <SuggestionItem {...item} />
39
- </InterceptingLink>
36
+ </Link>
40
37
  ))
41
38
  ) : (
42
39
  <Skeleton active paragraph={{ rows: 5 }} title={false} />
@@ -1,14 +1,14 @@
1
1
  import { ModelIcon } from '@lobehub/icons';
2
2
  import { ActionIcon, Grid } from '@lobehub/ui';
3
3
  import { Typography } from 'antd';
4
- import { createStyles } from 'antd-style';
4
+ import { createStyles, useResponsive } from 'antd-style';
5
5
  import { ChevronRightIcon } from 'lucide-react';
6
+ import Link from 'next/link';
6
7
  import { memo } from 'react';
7
8
  import { useTranslation } from 'react-i18next';
8
9
  import { Flexbox, FlexboxProps } from 'react-layout-kit';
9
10
  import urlJoin from 'url-join';
10
11
 
11
- import InterceptingLink from '@/components/InterceptingLink';
12
12
  import { DiscoverModelItem } from '@/types/discover';
13
13
  import { formatPriceByCurrency, formatTokenNumber } from '@/utils/format';
14
14
 
@@ -48,9 +48,12 @@ export interface SuggestionItemProps
48
48
 
49
49
  const ModelItem = memo<SuggestionItemProps>(({ mobile, meta, identifier }) => {
50
50
  const { title, tokens, vision, functionCall } = meta;
51
+ const { xl = true } = useResponsive();
51
52
  const { t } = useTranslation('discover');
52
53
  const { styles, theme } = useStyles();
53
54
 
55
+ const isMobile = mobile || !xl;
56
+
54
57
  const items: StatisticProps[] = [
55
58
  {
56
59
  title: t('models.contentLength'),
@@ -81,7 +84,7 @@ const ModelItem = memo<SuggestionItemProps>(({ mobile, meta, identifier }) => {
81
84
 
82
85
  const header = (
83
86
  <Flexbox gap={12}>
84
- <InterceptingLink href={urlJoin('/discover/model', identifier)} style={{ color: 'inherit' }}>
87
+ <Link href={urlJoin('/discover/model', identifier)} style={{ color: 'inherit' }}>
85
88
  <Flexbox align={'center'} gap={12} horizontal width={'100%'}>
86
89
  <ModelIcon model={identifier} size={36} type={'avatar'} />
87
90
  <Flexbox style={{ overflow: 'hidden' }}>
@@ -93,15 +96,15 @@ const ModelItem = memo<SuggestionItemProps>(({ mobile, meta, identifier }) => {
93
96
  </Paragraph>
94
97
  </Flexbox>
95
98
  </Flexbox>
96
- </InterceptingLink>
99
+ </Link>
97
100
  <ModelFeatureTags functionCall={functionCall} tokens={tokens} vision={vision} />
98
101
  </Flexbox>
99
102
  );
100
103
 
101
104
  const button = (
102
- <InterceptingLink href={urlJoin('/discover/model', identifier)} style={{ color: 'inherit' }}>
105
+ <Link href={urlJoin('/discover/model', identifier)} style={{ color: 'inherit' }}>
103
106
  <ActionIcon color={theme.colorTextDescription} icon={ChevronRightIcon} />
104
- </InterceptingLink>
107
+ </Link>
105
108
  );
106
109
 
107
110
  return (
@@ -113,7 +116,7 @@ const ModelItem = memo<SuggestionItemProps>(({ mobile, meta, identifier }) => {
113
116
  padding={16}
114
117
  wrap={'wrap'}
115
118
  >
116
- {mobile && (
119
+ {isMobile && (
117
120
  <Flexbox align={'center'} horizontal justify={'space-between'}>
118
121
  {header}
119
122
  {button}
@@ -125,13 +128,13 @@ const ModelItem = memo<SuggestionItemProps>(({ mobile, meta, identifier }) => {
125
128
  gap={16}
126
129
  horizontal
127
130
  maxItemWidth={100}
128
- rows={mobile ? 2 : items.length + 1}
131
+ rows={isMobile ? 2 : items.length + 1}
129
132
  style={{ minWidth: 240 }}
130
133
  >
131
- {!mobile && header}
134
+ {!isMobile && header}
132
135
  {items.map((item, index) => (
133
136
  <Statistic
134
- align={mobile ? 'flex-start' : 'center'}
137
+ align={isMobile ? 'flex-start' : 'center'}
135
138
  gap={4}
136
139
  key={index}
137
140
  valuePlacement={'bottom'}
@@ -140,7 +143,7 @@ const ModelItem = memo<SuggestionItemProps>(({ mobile, meta, identifier }) => {
140
143
  />
141
144
  ))}
142
145
  </Grid>
143
- {!mobile && button}
146
+ {!isMobile && button}
144
147
  </Flexbox>
145
148
  );
146
149
  });
@@ -1,8 +1,8 @@
1
1
  import { Grid } from '@lobehub/ui';
2
+ import Link from 'next/link';
2
3
  import { memo } from 'react';
3
4
  import urlJoin from 'url-join';
4
5
 
5
- import InterceptingLink from '@/components/InterceptingLink';
6
6
  import { DiscoverAssistantItem } from '@/types/discover';
7
7
 
8
8
  import Card from '../../assistants/features/Card';
@@ -11,20 +11,14 @@ const AssistantList = memo<{ data: DiscoverAssistantItem[] }>(({ data }) => {
11
11
  return (
12
12
  <Grid maxItemWidth={280} rows={4}>
13
13
  {data.slice(0, 8).map((item) => (
14
- <InterceptingLink
15
- href={urlJoin('/discover/assistant/', item.identifier)}
16
- key={item.identifier}
17
- >
14
+ <Link href={urlJoin('/discover/assistant/', item.identifier)} key={item.identifier}>
18
15
  <Card showCategory {...item} />
19
- </InterceptingLink>
16
+ </Link>
20
17
  ))}
21
18
  {data.slice(8, 16).map((item) => (
22
- <InterceptingLink
23
- href={urlJoin('/discover/assistant/', item.identifier)}
24
- key={item.identifier}
25
- >
19
+ <Link href={urlJoin('/discover/assistant/', item.identifier)} key={item.identifier}>
26
20
  <Card showCategory variant={'compact'} {...item} />
27
- </InterceptingLink>
21
+ </Link>
28
22
  ))}
29
23
  </Grid>
30
24
  );
@@ -1,8 +1,8 @@
1
1
  import { Grid } from '@lobehub/ui';
2
+ import Link from 'next/link';
2
3
  import { memo } from 'react';
3
4
  import urlJoin from 'url-join';
4
5
 
5
- import InterceptingLink from '@/components/InterceptingLink';
6
6
  import { DiscoverModelItem } from '@/types/discover';
7
7
 
8
8
  import Card from '../../models/features/Card';
@@ -11,9 +11,9 @@ const ModelList = memo<{ data: DiscoverModelItem[] }>(({ data }) => {
11
11
  return (
12
12
  <Grid maxItemWidth={280} rows={4}>
13
13
  {data.map((item) => (
14
- <InterceptingLink href={urlJoin('/discover/model/', item.identifier)} key={item.identifier}>
14
+ <Link href={urlJoin('/discover/model/', item.identifier)} key={item.identifier}>
15
15
  <Card {...item} />
16
- </InterceptingLink>
16
+ </Link>
17
17
  ))}
18
18
  </Grid>
19
19
  );
@@ -1,8 +1,8 @@
1
1
  import { Grid } from '@lobehub/ui';
2
+ import Link from 'next/link';
2
3
  import { memo } from 'react';
3
4
  import urlJoin from 'url-join';
4
5
 
5
- import InterceptingLink from '@/components/InterceptingLink';
6
6
  import { DiscoverPlugintem } from '@/types/discover';
7
7
 
8
8
  import Card from '../../plugins/features/Card';
@@ -11,12 +11,9 @@ const PluginList = memo<{ data: DiscoverPlugintem[] }>(({ data }) => {
11
11
  return (
12
12
  <Grid maxItemWidth={280} rows={4}>
13
13
  {data.map((item) => (
14
- <InterceptingLink
15
- href={urlJoin('/discover/plugin/', item.identifier)}
16
- key={item.identifier}
17
- >
14
+ <Link href={urlJoin('/discover/plugin/', item.identifier)} key={item.identifier}>
18
15
  <Card showCategory variant={'compact'} {...item} />
19
- </InterceptingLink>
16
+ </Link>
20
17
  ))}
21
18
  </Grid>
22
19
  );
@@ -2,11 +2,11 @@
2
2
 
3
3
  import { Grid } from '@lobehub/ui';
4
4
  import { Empty } from 'antd';
5
+ import Link from 'next/link';
5
6
  import { memo, useMemo } from 'react';
6
7
  import { useTranslation } from 'react-i18next';
7
8
  import urlJoin from 'url-join';
8
9
 
9
- import InterceptingLink from '@/components/InterceptingLink';
10
10
  import { DiscoverAssistantItem } from '@/types/discover';
11
11
 
12
12
  import SearchResultCount from '../../../components/SearchResultCount';
@@ -42,12 +42,9 @@ const List = memo<ListProps>(({ category, mobile, searchKeywords, items = [] })
42
42
  data={all}
43
43
  initialItemCount={24}
44
44
  itemContent={(_, item) => (
45
- <InterceptingLink
46
- href={urlJoin('/discover/assistant/', item.identifier)}
47
- key={item.identifier}
48
- >
45
+ <Link href={urlJoin('/discover/assistant/', item.identifier)} key={item.identifier}>
49
46
  <Card showCategory variant={'compact'} {...item} />
50
- </InterceptingLink>
47
+ </Link>
51
48
  )}
52
49
  style={{
53
50
  minHeight: '75vh',
@@ -62,12 +59,9 @@ const List = memo<ListProps>(({ category, mobile, searchKeywords, items = [] })
62
59
  <Title>{t('assistants.recentSubmits')}</Title>
63
60
  <Grid maxItemWidth={280} rows={4}>
64
61
  {recent.map((item) => (
65
- <InterceptingLink
66
- href={urlJoin('/discover/assistant/', item.identifier)}
67
- key={item.identifier}
68
- >
62
+ <Link href={urlJoin('/discover/assistant/', item.identifier)} key={item.identifier}>
69
63
  <Card showCategory={!category} {...item} />
70
- </InterceptingLink>
64
+ </Link>
71
65
  ))}
72
66
  </Grid>
73
67
  {last && last?.length > 0 && (
@@ -77,12 +71,9 @@ const List = memo<ListProps>(({ category, mobile, searchKeywords, items = [] })
77
71
  data={last}
78
72
  initialItemCount={12}
79
73
  itemContent={(_, item) => (
80
- <InterceptingLink
81
- href={urlJoin('/discover/assistant/', item.identifier)}
82
- key={item.identifier}
83
- >
74
+ <Link href={urlJoin('/discover/assistant/', item.identifier)} key={item.identifier}>
84
75
  <Card showCategory={!category} variant={'compact'} {...item} />
85
- </InterceptingLink>
76
+ </Link>
86
77
  )}
87
78
  style={{
88
79
  minHeight: '75vh',
@@ -1,11 +1,11 @@
1
1
  'use client';
2
2
 
3
3
  import { Empty } from 'antd';
4
+ import Link from 'next/link';
4
5
  import { memo } from 'react';
5
6
  import { useTranslation } from 'react-i18next';
6
7
  import urlJoin from 'url-join';
7
8
 
8
- import InterceptingLink from '@/components/InterceptingLink';
9
9
  import { DiscoverModelItem } from '@/types/discover';
10
10
 
11
11
  import SearchResultCount from '../../../components/SearchResultCount';
@@ -32,12 +32,9 @@ const List = memo<ListProps>(({ category, searchKeywords, items = [] }) => {
32
32
  data={items}
33
33
  initialItemCount={24}
34
34
  itemContent={(_, item) => (
35
- <InterceptingLink
36
- href={urlJoin('/discover/model/', item.identifier)}
37
- key={item.identifier}
38
- >
35
+ <Link href={urlJoin('/discover/model/', item.identifier)} key={item.identifier}>
39
36
  <Card showCategory {...item} />
40
- </InterceptingLink>
37
+ </Link>
41
38
  )}
42
39
  style={{
43
40
  minHeight: '75vh',
@@ -54,12 +51,9 @@ const List = memo<ListProps>(({ category, searchKeywords, items = [] }) => {
54
51
  data={items}
55
52
  initialItemCount={24}
56
53
  itemContent={(_, item) => (
57
- <InterceptingLink
58
- href={urlJoin('/discover/model/', item.identifier)}
59
- key={item.identifier}
60
- >
54
+ <Link href={urlJoin('/discover/model/', item.identifier)} key={item.identifier}>
61
55
  <Card showCategory={!category} {...item} />
62
- </InterceptingLink>
56
+ </Link>
63
57
  )}
64
58
  style={{
65
59
  minHeight: '75vh',
@@ -2,11 +2,11 @@
2
2
 
3
3
  import { Grid } from '@lobehub/ui';
4
4
  import { Empty } from 'antd';
5
+ import Link from 'next/link';
5
6
  import { memo, useMemo } from 'react';
6
7
  import { useTranslation } from 'react-i18next';
7
8
  import urlJoin from 'url-join';
8
9
 
9
- import InterceptingLink from '@/components/InterceptingLink';
10
10
  import { DiscoverPlugintem } from '@/types/discover';
11
11
 
12
12
  import SearchResultCount from '../../../components/SearchResultCount';
@@ -41,12 +41,9 @@ const List = memo<ListProps>(({ category, mobile, searchKeywords, items = [] })
41
41
  data={all}
42
42
  initialItemCount={24}
43
43
  itemContent={(_, item) => (
44
- <InterceptingLink
45
- href={urlJoin('/discover/plugin/', item.identifier)}
46
- key={item.identifier}
47
- >
44
+ <Link href={urlJoin('/discover/plugin/', item.identifier)} key={item.identifier}>
48
45
  <Card showCategory variant={'compact'} {...item} />
49
- </InterceptingLink>
46
+ </Link>
50
47
  )}
51
48
  style={{
52
49
  minHeight: '75vh',
@@ -61,12 +58,9 @@ const List = memo<ListProps>(({ category, mobile, searchKeywords, items = [] })
61
58
  <Title>{t('plugins.recentSubmits')}</Title>
62
59
  <Grid maxItemWidth={280} rows={4}>
63
60
  {recent.map((item) => (
64
- <InterceptingLink
65
- href={urlJoin('/discover/plugin/', item.identifier)}
66
- key={item.identifier}
67
- >
61
+ <Link href={urlJoin('/discover/plugin/', item.identifier)} key={item.identifier}>
68
62
  <Card showCategory={!category} {...item} />
69
- </InterceptingLink>
63
+ </Link>
70
64
  ))}
71
65
  </Grid>
72
66
  {last && last?.length > 0 && (
@@ -76,12 +70,9 @@ const List = memo<ListProps>(({ category, mobile, searchKeywords, items = [] })
76
70
  data={last}
77
71
  initialItemCount={12}
78
72
  itemContent={(_, item) => (
79
- <InterceptingLink
80
- href={urlJoin('/discover/plugin/', item.identifier)}
81
- key={item.identifier}
82
- >
73
+ <Link href={urlJoin('/discover/plugin/', item.identifier)} key={item.identifier}>
83
74
  <Card showCategory={!category} variant={'compact'} {...item} />
84
- </InterceptingLink>
75
+ </Link>
85
76
  )}
86
77
  style={{
87
78
  minHeight: '75vh',
@@ -1,11 +1,11 @@
1
1
  'use client';
2
2
 
3
3
  import { Empty } from 'antd';
4
+ import Link from 'next/link';
4
5
  import { memo } from 'react';
5
6
  import { useTranslation } from 'react-i18next';
6
7
  import urlJoin from 'url-join';
7
8
 
8
- import InterceptingLink from '@/components/InterceptingLink';
9
9
  import { DiscoverProviderItem } from '@/types/discover';
10
10
 
11
11
  import SearchResultCount from '../../../components/SearchResultCount';
@@ -31,12 +31,9 @@ const List = memo<ListProps>(({ searchKeywords, items = [], mobile }) => {
31
31
  data={items}
32
32
  initialItemCount={6}
33
33
  itemContent={(_, item) => (
34
- <InterceptingLink
35
- href={urlJoin('/discover/provider/', item.identifier)}
36
- key={item.identifier}
37
- >
34
+ <Link href={urlJoin('/discover/provider/', item.identifier)} key={item.identifier}>
38
35
  <Card {...item} mobile={mobile} style={{ minHeight: 'unset' }} />
39
- </InterceptingLink>
36
+ </Link>
40
37
  )}
41
38
  style={{
42
39
  minHeight: '75vh',
@@ -53,12 +50,9 @@ const List = memo<ListProps>(({ searchKeywords, items = [], mobile }) => {
53
50
  data={items}
54
51
  initialItemCount={6}
55
52
  itemContent={(_, item) => (
56
- <InterceptingLink
57
- href={urlJoin('/discover/provider/', item.identifier)}
58
- key={item.identifier}
59
- >
53
+ <Link href={urlJoin('/discover/provider/', item.identifier)} key={item.identifier}>
60
54
  <Card {...item} mobile={mobile} style={{ minHeight: 'unset' }} />
61
- </InterceptingLink>
55
+ </Link>
62
56
  )}
63
57
  style={{
64
58
  minHeight: '75vh',
@@ -1,11 +1,14 @@
1
1
  import { PropsWithChildren } from 'react';
2
2
  import { Flexbox } from 'react-layout-kit';
3
3
 
4
+ import NProgress from '@/components/NProgress';
5
+
4
6
  import Header from './Header';
5
7
 
6
8
  const Layout = ({ children }: PropsWithChildren) => {
7
9
  return (
8
10
  <>
11
+ <NProgress />
9
12
  <Flexbox height={'100%'} style={{ overflow: 'hidden', position: 'relative' }} width={'100%'}>
10
13
  <Header />
11
14
  {children}
@@ -1,7 +1,14 @@
1
1
  import { PropsWithChildren } from 'react';
2
2
 
3
+ import NProgress from '@/components/NProgress';
4
+
3
5
  const Layout = ({ children }: PropsWithChildren) => {
4
- return children;
6
+ return (
7
+ <>
8
+ <NProgress />
9
+ {children}
10
+ </>
11
+ );
5
12
  };
6
13
 
7
14
  Layout.displayName = 'MobileDiscoverStoreLayout';