@lobehub/lobehub 2.0.0-next.311 → 2.0.0-next.313

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 (151) hide show
  1. package/CHANGELOG.md +59 -0
  2. package/apps/desktop/src/main/controllers/AuthCtr.ts +75 -7
  3. package/changelog/v1.json +21 -0
  4. package/docs/usage/providers/internlm.mdx +2 -2
  5. package/docs/usage/providers/internlm.zh-CN.mdx +3 -3
  6. package/e2e/README.md +1 -1
  7. package/e2e/src/features/community/detail-pages.feature +2 -2
  8. package/e2e/src/features/community/interactions.feature +5 -5
  9. package/e2e/src/features/community/smoke.feature +1 -1
  10. package/e2e/src/steps/community/detail-pages.steps.ts +6 -4
  11. package/e2e/src/steps/community/interactions.steps.ts +3 -3
  12. package/locales/en-US/error.json +10 -1
  13. package/locales/en-US/subscription.json +1 -1
  14. package/locales/zh-CN/desktop-onboarding.json +5 -0
  15. package/locales/zh-CN/error.json +10 -1
  16. package/locales/zh-CN/subscription.json +1 -1
  17. package/package.json +1 -1
  18. package/packages/agent-runtime/src/agents/GeneralChatAgent.ts +14 -2
  19. package/packages/agent-runtime/src/agents/__tests__/GeneralChatAgent.test.ts +275 -1
  20. package/packages/builtin-tool-agent-builder/src/systemRole.ts +9 -0
  21. package/packages/builtin-tool-cloud-sandbox/package.json +1 -0
  22. package/packages/builtin-tool-cloud-sandbox/src/ExecutionRuntime/index.ts +105 -134
  23. package/packages/builtin-tool-cloud-sandbox/src/executor/index.ts +254 -0
  24. package/packages/builtin-tool-cloud-sandbox/src/index.ts +1 -0
  25. package/packages/builtin-tool-cloud-sandbox/src/types/api.ts +22 -0
  26. package/packages/builtin-tool-cloud-sandbox/src/types/index.ts +4 -0
  27. package/packages/builtin-tool-cloud-sandbox/src/types/params.ts +85 -0
  28. package/packages/builtin-tool-cloud-sandbox/src/types/service.ts +48 -0
  29. package/packages/builtin-tool-cloud-sandbox/src/{types.ts → types/state.ts} +0 -23
  30. package/packages/builtin-tool-memory/src/manifest.ts +5 -5
  31. package/packages/editor-runtime/src/__tests__/EditorRuntime.real.test.ts +1 -1
  32. package/packages/editor-runtime/src/__tests__/EditorRuntime.test.ts +1 -1
  33. package/packages/electron-client-ipc/src/events/index.ts +5 -1
  34. package/packages/electron-client-ipc/src/events/remoteServer.ts +23 -0
  35. package/packages/memory-user-memory/src/schemas/index.ts +0 -1
  36. package/packages/model-bank/src/modelProviders/internlm.ts +1 -1
  37. package/packages/model-runtime/src/core/RouterRuntime/createRuntime.ts +5 -15
  38. package/packages/model-runtime/src/providers/internlm/index.test.ts +15 -15
  39. package/packages/model-runtime/src/providers/internlm/index.ts +1 -1
  40. package/packages/types/src/tool/intervention.ts +4 -2
  41. package/packages/types/src/user/preference.ts +1 -0
  42. package/public/favicon-32x-32-error.ico +0 -0
  43. package/public/favicon-32x32-done-dev.ico +0 -0
  44. package/public/favicon-32x32-done.ico +0 -0
  45. package/public/favicon-32x32-error-dev.ico +0 -0
  46. package/public/favicon-32x32-progress-dev.ico +0 -0
  47. package/public/favicon-32x32-progress.ico +0 -0
  48. package/public/favicon-done-dev.ico +0 -0
  49. package/public/favicon-done.ico +0 -0
  50. package/public/favicon-error-dev.ico +0 -0
  51. package/public/favicon-error.ico +0 -0
  52. package/public/favicon-progress-dev.ico +0 -0
  53. package/public/favicon-progress.ico +0 -0
  54. package/src/app/[variants]/(desktop)/desktop-onboarding/features/LoginStep.tsx +84 -26
  55. package/src/app/[variants]/(main)/_layout/DesktopAutoOidcOnFirstOpen.tsx +4 -0
  56. package/src/app/[variants]/(main)/agent/profile/features/Header/AgentPublishButton/PublishResultModal.tsx +1 -1
  57. package/src/app/[variants]/(main)/community/(detail)/_layout/Header.tsx +15 -3
  58. package/src/app/[variants]/(main)/community/(detail)/{assistant → agent}/features/Details/Overview/TagList.tsx +1 -1
  59. package/src/app/[variants]/(main)/community/(detail)/{assistant → agent}/features/Details/Related/index.tsx +2 -2
  60. package/src/app/[variants]/(main)/community/(detail)/{assistant → agent}/features/Details/SystemRole/TagList.tsx +1 -1
  61. package/src/app/[variants]/(main)/community/(detail)/{assistant → agent}/features/Details/SystemRole/index.tsx +1 -1
  62. package/src/app/[variants]/(main)/community/(detail)/{assistant → agent}/features/Header.tsx +2 -2
  63. package/src/app/[variants]/(main)/community/(detail)/{assistant → agent}/features/Sidebar/ActionButton/AddAgent.tsx +1 -1
  64. package/src/app/[variants]/(main)/community/(detail)/{assistant → agent}/features/Sidebar/ActionButton/index.tsx +1 -1
  65. package/src/app/[variants]/(main)/community/(detail)/{assistant → agent}/features/Sidebar/Related/index.tsx +2 -2
  66. package/src/app/[variants]/(main)/community/(detail)/{assistant → agent}/features/StatusPage/index.tsx +2 -2
  67. package/src/app/[variants]/(main)/community/(detail)/user/features/UserAgentCard.tsx +2 -2
  68. package/src/app/[variants]/(main)/community/(detail)/user/features/UserFavoriteAgents.tsx +1 -1
  69. package/src/app/[variants]/(main)/community/(list)/(home)/index.tsx +2 -2
  70. package/src/app/[variants]/(main)/community/(list)/(home)/loading.tsx +1 -1
  71. package/src/app/[variants]/(main)/community/(list)/{assistant → agent}/Client.tsx +5 -1
  72. package/src/app/[variants]/(main)/community/(list)/{assistant → agent}/features/Category/index.tsx +1 -1
  73. package/src/app/[variants]/(main)/community/(list)/{assistant → agent}/features/List/Item.tsx +1 -1
  74. package/src/app/[variants]/(main)/community/(list)/{assistant → agent}/features/MarketSourceSwitch.tsx +1 -1
  75. package/src/app/[variants]/(main)/community/_layout/Sidebar/Header/Nav.tsx +2 -2
  76. package/src/app/[variants]/(main)/home/features/CommunityAgents/List.tsx +1 -1
  77. package/src/app/[variants]/(main)/home/features/CommunityAgents/index.tsx +1 -1
  78. package/src/app/[variants]/(mobile)/_layout/index.tsx +1 -1
  79. package/src/app/[variants]/(mobile)/router/mobileRouter.config.tsx +6 -6
  80. package/src/app/[variants]/router/desktopRouter.config.tsx +8 -8
  81. package/src/app/[variants]/share/t/[id]/_layout/index.tsx +1 -1
  82. package/src/business/server/user.ts +4 -0
  83. package/src/features/CommandMenu/SearchResults.tsx +1 -1
  84. package/src/features/Conversation/Messages/Task/Actions/index.tsx +0 -2
  85. package/src/features/Conversation/Messages/Task/index.tsx +1 -1
  86. package/src/features/Conversation/Messages/Tasks/shared/ProcessingState.tsx +0 -2
  87. package/src/features/Electron/navigation/routeMetadata.ts +1 -1
  88. package/src/features/NavPanel/components/NavPanelDraggable.tsx +0 -14
  89. package/src/features/ResourceManager/components/Explorer/ItemDropdown/useFileItemDropdown.tsx +4 -3
  90. package/src/features/SharePopover/index.tsx +5 -3
  91. package/src/hooks/useAppOrigin.ts +16 -0
  92. package/src/layout/GlobalProvider/FaviconProvider.tsx +92 -0
  93. package/src/layout/GlobalProvider/index.tsx +15 -11
  94. package/src/layout/GlobalProvider/useUserStateRedirect.ts +37 -24
  95. package/src/libs/next/config/define-config.ts +1 -1
  96. package/src/libs/trusted-client/index.ts +2 -5
  97. package/src/locales/default/desktop-onboarding.ts +5 -0
  98. package/src/locales/default/error.ts +11 -0
  99. package/src/locales/default/subscription.ts +1 -1
  100. package/src/server/modules/AgentRuntime/RuntimeExecutors.ts +2 -0
  101. package/src/server/routers/lambda/user.ts +24 -10
  102. package/src/server/services/agentRuntime/AgentRuntimeService.test.ts +3 -0
  103. package/src/server/services/agentRuntime/AgentRuntimeService.ts +8 -5
  104. package/src/server/services/agentRuntime/types.ts +7 -0
  105. package/src/server/services/aiAgent/__tests__/execGroupSubAgentTask.test.ts +3 -0
  106. package/src/server/services/aiAgent/index.ts +10 -4
  107. package/src/server/services/market/index.ts +7 -0
  108. package/src/server/services/sandbox/index.ts +120 -0
  109. package/src/server/services/toolExecution/builtin.ts +12 -18
  110. package/src/server/services/toolExecution/index.ts +1 -1
  111. package/src/server/services/toolExecution/serverRuntimes/cloudSandbox.ts +31 -0
  112. package/src/server/services/toolExecution/serverRuntimes/index.ts +55 -0
  113. package/src/server/services/toolExecution/serverRuntimes/types.ts +14 -0
  114. package/src/server/services/toolExecution/serverRuntimes/webBrowsing.ts +20 -0
  115. package/src/server/services/toolExecution/types.ts +2 -0
  116. package/src/server/sitemap.test.ts +5 -5
  117. package/src/server/sitemap.ts +3 -3
  118. package/src/services/{codeInterpreter.ts → cloudSandbox.ts} +3 -3
  119. package/src/services/electron/remoteServer.ts +8 -0
  120. package/src/store/chat/agents/GroupOrchestration/__tests__/batch-exec-async-tasks.test.ts +626 -0
  121. package/src/store/chat/agents/GroupOrchestration/createGroupOrchestrationExecutors.ts +294 -0
  122. package/src/store/chat/slices/plugin/action.test.ts +0 -48
  123. package/src/store/chat/slices/plugin/actions/pluginTypes.ts +0 -131
  124. package/src/store/tool/slices/builtin/executors/index.ts +2 -0
  125. package/src/store/user/slices/settings/selectors/toolIntervention.test.ts +143 -0
  126. package/src/store/user/slices/settings/selectors/toolIntervention.ts +11 -2
  127. package/packages/memory-user-memory/src/schemas/jsonSchemas.ts +0 -37
  128. /package/src/app/[variants]/(main)/community/(detail)/{assistant → agent}/features/DetailProvider.tsx +0 -0
  129. /package/src/app/[variants]/(main)/community/(detail)/{assistant → agent}/features/Details/Capabilities/Block.tsx +0 -0
  130. /package/src/app/[variants]/(main)/community/(detail)/{assistant → agent}/features/Details/Capabilities/Knowledge.tsx +0 -0
  131. /package/src/app/[variants]/(main)/community/(detail)/{assistant → agent}/features/Details/Capabilities/KnowledgeItem.tsx +0 -0
  132. /package/src/app/[variants]/(main)/community/(detail)/{assistant → agent}/features/Details/Capabilities/PluginItem.tsx +0 -0
  133. /package/src/app/[variants]/(main)/community/(detail)/{assistant → agent}/features/Details/Capabilities/Plugins.tsx +0 -0
  134. /package/src/app/[variants]/(main)/community/(detail)/{assistant → agent}/features/Details/Capabilities/index.tsx +0 -0
  135. /package/src/app/[variants]/(main)/community/(detail)/{assistant → agent}/features/Details/Nav.tsx +0 -0
  136. /package/src/app/[variants]/(main)/community/(detail)/{assistant → agent}/features/Details/Overview/index.tsx +0 -0
  137. /package/src/app/[variants]/(main)/community/(detail)/{assistant → agent}/features/Details/Versions/index.tsx +0 -0
  138. /package/src/app/[variants]/(main)/community/(detail)/{assistant → agent}/features/Details/index.tsx +0 -0
  139. /package/src/app/[variants]/(main)/community/(detail)/{assistant → agent}/features/Sidebar/Related/Item.tsx +0 -0
  140. /package/src/app/[variants]/(main)/community/(detail)/{assistant → agent}/features/Sidebar/Summary/index.tsx +0 -0
  141. /package/src/app/[variants]/(main)/community/(detail)/{assistant → agent}/features/Sidebar/TocList/index.tsx +0 -0
  142. /package/src/app/[variants]/(main)/community/(detail)/{assistant → agent}/features/Sidebar/index.tsx +0 -0
  143. /package/src/app/[variants]/(main)/community/(detail)/{assistant → agent}/index.tsx +0 -0
  144. /package/src/app/[variants]/(main)/community/(detail)/{assistant → agent}/loading.tsx +0 -0
  145. /package/src/app/[variants]/(main)/community/(list)/{assistant → agent}/_layout/index.tsx +0 -0
  146. /package/src/app/[variants]/(main)/community/(list)/{assistant → agent}/_layout/style.ts +0 -0
  147. /package/src/app/[variants]/(main)/community/(list)/{assistant → agent}/features/Category/useCategory.tsx +0 -0
  148. /package/src/app/[variants]/(main)/community/(list)/{assistant → agent}/features/List/TokenTag.tsx +0 -0
  149. /package/src/app/[variants]/(main)/community/(list)/{assistant → agent}/features/List/index.tsx +0 -0
  150. /package/src/app/[variants]/(main)/community/(list)/{assistant → agent}/index.tsx +0 -0
  151. /package/src/app/[variants]/(main)/community/(list)/{assistant → agent}/loading.tsx +0 -0
@@ -9,7 +9,7 @@ import { LobeInternLMAI, params } from './index';
9
9
  testProvider({
10
10
  Runtime: LobeInternLMAI,
11
11
  provider: ModelProvider.InternLM,
12
- defaultBaseURL: 'https://internlm-chat.intern-ai.org.cn/puyu/api/v1',
12
+ defaultBaseURL: 'https://chat.intern-ai.org.cn/api/v1',
13
13
  chatDebugEnv: 'DEBUG_INTERNLM_CHAT_COMPLETION',
14
14
  chatModel: 'internlm2_5-7b-chat',
15
15
  test: {
@@ -30,7 +30,7 @@ describe('LobeInternLMAI - custom features', () => {
30
30
 
31
31
  describe('params object', () => {
32
32
  it('should export params with correct baseURL', () => {
33
- expect(params.baseURL).toBe('https://internlm-chat.intern-ai.org.cn/puyu/api/v1');
33
+ expect(params.baseURL).toBe('https://chat.intern-ai.org.cn/api/v1');
34
34
  });
35
35
 
36
36
  it('should have correct provider', () => {
@@ -116,7 +116,7 @@ describe('LobeInternLMAI - custom features', () => {
116
116
  describe('models', () => {
117
117
  it('should fetch and process models', async () => {
118
118
  const mockClient = {
119
- baseURL: 'https://internlm-chat.intern-ai.org.cn/puyu/api/v1',
119
+ baseURL: 'https://chat.intern-ai.org.cn/api/v1',
120
120
  apiKey: 'test',
121
121
  models: {
122
122
  list: vi.fn().mockResolvedValue({
@@ -137,7 +137,7 @@ describe('LobeInternLMAI - custom features', () => {
137
137
 
138
138
  it('should detect function call capability from model name', async () => {
139
139
  const mockClient = {
140
- baseURL: 'https://internlm-chat.intern-ai.org.cn/puyu/api/v1',
140
+ baseURL: 'https://chat.intern-ai.org.cn/api/v1',
141
141
  apiKey: 'test',
142
142
  models: {
143
143
  list: vi.fn().mockResolvedValue({
@@ -156,7 +156,7 @@ describe('LobeInternLMAI - custom features', () => {
156
156
 
157
157
  it('should detect vision capability from model name', async () => {
158
158
  const mockClient = {
159
- baseURL: 'https://internlm-chat.intern-ai.org.cn/puyu/api/v1',
159
+ baseURL: 'https://chat.intern-ai.org.cn/api/v1',
160
160
  apiKey: 'test',
161
161
  models: {
162
162
  list: vi.fn().mockResolvedValue({
@@ -175,7 +175,7 @@ describe('LobeInternLMAI - custom features', () => {
175
175
 
176
176
  it('should handle case-insensitive keyword matching', async () => {
177
177
  const mockClient = {
178
- baseURL: 'https://internlm-chat.intern-ai.org.cn/puyu/api/v1',
178
+ baseURL: 'https://chat.intern-ai.org.cn/api/v1',
179
179
  apiKey: 'test',
180
180
  models: {
181
181
  list: vi.fn().mockResolvedValue({
@@ -194,7 +194,7 @@ describe('LobeInternLMAI - custom features', () => {
194
194
 
195
195
  it('should merge with known model data from model-bank', async () => {
196
196
  const mockClient = {
197
- baseURL: 'https://internlm-chat.intern-ai.org.cn/puyu/api/v1',
197
+ baseURL: 'https://chat.intern-ai.org.cn/api/v1',
198
198
  apiKey: 'test',
199
199
  models: {
200
200
  list: vi.fn().mockResolvedValue({
@@ -215,7 +215,7 @@ describe('LobeInternLMAI - custom features', () => {
215
215
 
216
216
  it('should handle models not in model-bank', async () => {
217
217
  const mockClient = {
218
- baseURL: 'https://internlm-chat.intern-ai.org.cn/puyu/api/v1',
218
+ baseURL: 'https://chat.intern-ai.org.cn/api/v1',
219
219
  apiKey: 'test',
220
220
  models: {
221
221
  list: vi.fn().mockResolvedValue({
@@ -238,7 +238,7 @@ describe('LobeInternLMAI - custom features', () => {
238
238
 
239
239
  it('should set enabled flag from known model', async () => {
240
240
  const mockClient = {
241
- baseURL: 'https://internlm-chat.intern-ai.org.cn/puyu/api/v1',
241
+ baseURL: 'https://chat.intern-ai.org.cn/api/v1',
242
242
  apiKey: 'test',
243
243
  models: {
244
244
  list: vi.fn().mockResolvedValue({
@@ -255,7 +255,7 @@ describe('LobeInternLMAI - custom features', () => {
255
255
 
256
256
  it('should inherit abilities from known model', async () => {
257
257
  const mockClient = {
258
- baseURL: 'https://internlm-chat.intern-ai.org.cn/puyu/api/v1',
258
+ baseURL: 'https://chat.intern-ai.org.cn/api/v1',
259
259
  apiKey: 'test',
260
260
  models: {
261
261
  list: vi.fn().mockResolvedValue({
@@ -291,7 +291,7 @@ describe('LobeInternLMAI - custom features', () => {
291
291
 
292
292
  it('should handle empty model list', async () => {
293
293
  const mockClient = {
294
- baseURL: 'https://internlm-chat.intern-ai.org.cn/puyu/api/v1',
294
+ baseURL: 'https://chat.intern-ai.org.cn/api/v1',
295
295
  apiKey: 'test',
296
296
  models: {
297
297
  list: vi.fn().mockResolvedValue({
@@ -306,7 +306,7 @@ describe('LobeInternLMAI - custom features', () => {
306
306
 
307
307
  it('should filter out null/undefined models', async () => {
308
308
  const mockClient = {
309
- baseURL: 'https://internlm-chat.intern-ai.org.cn/puyu/api/v1',
309
+ baseURL: 'https://chat.intern-ai.org.cn/api/v1',
310
310
  apiKey: 'test',
311
311
  models: {
312
312
  list: vi.fn().mockResolvedValue({
@@ -322,7 +322,7 @@ describe('LobeInternLMAI - custom features', () => {
322
322
 
323
323
  it('should set contextWindowTokens from known model', async () => {
324
324
  const mockClient = {
325
- baseURL: 'https://internlm-chat.intern-ai.org.cn/puyu/api/v1',
325
+ baseURL: 'https://chat.intern-ai.org.cn/api/v1',
326
326
  apiKey: 'test',
327
327
  models: {
328
328
  list: vi.fn().mockResolvedValue({
@@ -340,7 +340,7 @@ describe('LobeInternLMAI - custom features', () => {
340
340
 
341
341
  it('should set displayName from known model', async () => {
342
342
  const mockClient = {
343
- baseURL: 'https://internlm-chat.intern-ai.org.cn/puyu/api/v1',
343
+ baseURL: 'https://chat.intern-ai.org.cn/api/v1',
344
344
  apiKey: 'test',
345
345
  models: {
346
346
  list: vi.fn().mockResolvedValue({
@@ -358,7 +358,7 @@ describe('LobeInternLMAI - custom features', () => {
358
358
 
359
359
  it('should combine keyword detection with known model abilities', async () => {
360
360
  const mockClient = {
361
- baseURL: 'https://internlm-chat.intern-ai.org.cn/puyu/api/v1',
361
+ baseURL: 'https://chat.intern-ai.org.cn/api/v1',
362
362
  apiKey: 'test',
363
363
  models: {
364
364
  list: vi.fn().mockResolvedValue({
@@ -11,7 +11,7 @@ export interface InternLMModelCard {
11
11
  }
12
12
 
13
13
  export const params = {
14
- baseURL: 'https://internlm-chat.intern-ai.org.cn/puyu/api/v1',
14
+ baseURL: 'https://chat.intern-ai.org.cn/api/v1',
15
15
  chatCompletion: {
16
16
  handlePayload: (payload) => {
17
17
  return {
@@ -138,13 +138,15 @@ export interface UserInterventionConfig {
138
138
  * - auto-run: Automatically approve all tools without user consent
139
139
  * - allow-list: Only approve tools in the allow list
140
140
  * - manual: Use tool's own humanIntervention config (default)
141
+ * - headless: Fully automated mode for async tasks - all tools execute automatically,
142
+ * security blacklist tools are skipped (not blocked)
141
143
  */
142
- approvalMode: 'auto-run' | 'allow-list' | 'manual';
144
+ approvalMode: 'auto-run' | 'allow-list' | 'manual' | 'headless';
143
145
  }
144
146
 
145
147
  export const UserInterventionConfigSchema = z.object({
146
148
  allowList: z.array(z.string()).optional(),
147
- approvalMode: z.enum(['auto-run', 'allow-list', 'manual']),
149
+ approvalMode: z.enum(['auto-run', 'allow-list', 'manual', 'headless']),
148
150
  });
149
151
 
150
152
  /**
@@ -84,6 +84,7 @@ export interface UserInitializationState {
84
84
  hasConversation?: boolean;
85
85
  interests?: string[];
86
86
  isFreePlan?: boolean;
87
+ isInviteCodeRequired?: boolean;
87
88
  isInWaitList?: boolean;
88
89
  /** @deprecated Use onboarding field instead */
89
90
  isOnboard?: boolean;
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
@@ -1,6 +1,6 @@
1
1
  'use client';
2
2
 
3
- import { useWatchBroadcast } from '@lobechat/electron-client-ipc';
3
+ import { AuthorizationProgress, useWatchBroadcast } from '@lobechat/electron-client-ipc';
4
4
  import { Alert, Button, Center, Flexbox, Icon, Input, Text } from '@lobehub/ui';
5
5
  import { Divider } from 'antd';
6
6
  import { cssVar } from 'antd-style';
@@ -9,6 +9,7 @@ import { memo, useEffect, useState } from 'react';
9
9
  import { useTranslation } from 'react-i18next';
10
10
 
11
11
  import { isDesktop } from '@/const/version';
12
+ import { remoteServerService } from '@/services/electron/remoteServer';
12
13
  import { useElectronStore } from '@/store/electron';
13
14
  import { setDesktopAutoOidcFirstOpenHandled } from '@/utils/electron/autoOidc';
14
15
 
@@ -44,6 +45,7 @@ const LoginStep = memo<LoginStepProps>(({ onBack, onNext }) => {
44
45
  const { t } = useTranslation('desktop-onboarding');
45
46
  const [endpoint, setEndpoint] = useState('');
46
47
  const [cloudLoginStatus, setCloudLoginStatus] = useState<LoginStatus>('idle');
48
+ const [authProgress, setAuthProgress] = useState<AuthorizationProgress | null>(null);
47
49
  const [selfhostLoginStatus, setSelfhostLoginStatus] = useState<LoginStatus>('idle');
48
50
  const [remoteError, setRemoteError] = useState<string | null>(null);
49
51
  const [isSigningOut, setIsSigningOut] = useState(false);
@@ -164,29 +166,53 @@ const LoginStep = memo<LoginStepProps>(({ onBack, onNext }) => {
164
166
  useWatchBroadcast('authorizationSuccessful', async () => {
165
167
  setRemoteError(null);
166
168
  clearRemoteServerSyncError();
169
+ setAuthProgress(null);
167
170
  await refreshServerConfig();
168
171
  });
169
172
 
170
173
  useWatchBroadcast('authorizationFailed', ({ error }) => {
171
174
  setRemoteError(error);
175
+ setAuthProgress(null);
172
176
  if (cloudLoginStatus === 'loading') setCloudLoginStatus('error');
173
177
  if (selfhostLoginStatus === 'loading') setSelfhostLoginStatus('error');
174
178
  });
175
179
 
180
+ useWatchBroadcast('authorizationProgress', (progress) => {
181
+ setAuthProgress(progress);
182
+ if (progress.phase === 'cancelled') {
183
+ setCloudLoginStatus('idle');
184
+ setAuthProgress(null);
185
+ }
186
+ });
187
+
188
+ const handleCancelAuth = async () => {
189
+ await remoteServerService.cancelAuthorization();
190
+ setCloudLoginStatus('idle');
191
+ setAuthProgress(null);
192
+ };
193
+
176
194
  // 渲染 Cloud 登录内容
177
195
  const renderCloudContent = () => {
178
196
  if (cloudLoginStatus === 'success') {
179
197
  return (
180
- <Button
181
- block
182
- disabled={isSigningOut || isConnectingServer}
183
- icon={Cloud}
184
- onClick={handleSignOut}
185
- size={'large'}
186
- type={'default'}
187
- >
188
- {isSigningOut ? t('screen5.actions.signingOut') : t('screen5.actions.signOut')}
189
- </Button>
198
+ <Flexbox gap={12} style={{ width: '100%' }}>
199
+ <Alert
200
+ description={t('authResult.success.desc')}
201
+ style={{ width: '100%' }}
202
+ title={t('authResult.success.title')}
203
+ type={'success'}
204
+ />
205
+ <Button
206
+ block
207
+ disabled={isSigningOut || isConnectingServer}
208
+ icon={Cloud}
209
+ onClick={handleSignOut}
210
+ size={'large'}
211
+ type={'default'}
212
+ >
213
+ {isSigningOut ? t('screen5.actions.signingOut') : t('screen5.actions.signOut')}
214
+ </Button>
215
+ </Flexbox>
190
216
  );
191
217
  }
192
218
 
@@ -212,19 +238,43 @@ const LoginStep = memo<LoginStepProps>(({ onBack, onNext }) => {
212
238
  );
213
239
  }
214
240
 
241
+ if (cloudLoginStatus === 'loading') {
242
+ return (
243
+ <Flexbox gap={8} style={{ width: '100%' }}>
244
+ <Button block disabled={true} icon={Cloud} loading={true} size={'large'} type={'primary'}>
245
+ {authProgress
246
+ ? t(`screen5.auth.phase.${authProgress.phase}`, {
247
+ defaultValue: t('screen5.actions.signingIn'),
248
+ })
249
+ : t('screen5.actions.signingIn')}
250
+ </Button>
251
+ {authProgress && (
252
+ <Flexbox align={'center'} horizontal justify={'space-between'}>
253
+ <Text style={{ color: cssVar.colorTextDescription }} type={'secondary'}>
254
+ {t('screen5.auth.remaining', {
255
+ time: Math.round((authProgress.maxPollTime - authProgress.elapsed) / 1000),
256
+ })}
257
+ </Text>
258
+ <Button onClick={handleCancelAuth} size={'small'} type={'text'}>
259
+ {t('screen5.actions.cancel')}
260
+ </Button>
261
+ </Flexbox>
262
+ )}
263
+ </Flexbox>
264
+ );
265
+ }
266
+
215
267
  return (
216
268
  <Button
217
269
  block
218
- disabled={cloudLoginStatus === 'loading' || isConnectingServer}
270
+ disabled={isConnectingServer}
219
271
  icon={Cloud}
220
- loading={cloudLoginStatus === 'loading'}
272
+ loading={false}
221
273
  onClick={handleCloudLogin}
222
274
  size={'large'}
223
275
  type={'primary'}
224
276
  >
225
- {cloudLoginStatus === 'loading'
226
- ? t('screen5.actions.signingIn')
227
- : t('screen5.actions.signInCloud')}
277
+ {t('screen5.actions.signInCloud')}
228
278
  </Button>
229
279
  );
230
280
  };
@@ -233,16 +283,24 @@ const LoginStep = memo<LoginStepProps>(({ onBack, onNext }) => {
233
283
  const renderSelfhostContent = () => {
234
284
  if (selfhostLoginStatus === 'success') {
235
285
  return (
236
- <Button
237
- block
238
- disabled={isSigningOut || isConnectingServer}
239
- icon={Server}
240
- onClick={handleSignOut}
241
- size={'large'}
242
- type={'default'}
243
- >
244
- {isSigningOut ? t('screen5.actions.signingOut') : t('screen5.actions.signOut')}
245
- </Button>
286
+ <Flexbox gap={12} style={{ width: '100%' }}>
287
+ <Alert
288
+ description={t('authResult.success.desc')}
289
+ style={{ width: '100%' }}
290
+ title={t('authResult.success.title')}
291
+ type={'success'}
292
+ />
293
+ <Button
294
+ block
295
+ disabled={isSigningOut || isConnectingServer}
296
+ icon={Server}
297
+ onClick={handleSignOut}
298
+ size={'large'}
299
+ type={'default'}
300
+ >
301
+ {isSigningOut ? t('screen5.actions.signingOut') : t('screen5.actions.signOut')}
302
+ </Button>
303
+ </Flexbox>
246
304
  );
247
305
  }
248
306
 
@@ -2,6 +2,7 @@
2
2
 
3
3
  import { memo, useEffect } from 'react';
4
4
 
5
+ import { getDesktopOnboardingCompleted } from '@/app/[variants]/(desktop)/desktop-onboarding/storage';
5
6
  import { useElectronStore } from '@/store/electron';
6
7
  import {
7
8
  getDesktopAutoOidcFirstOpenHandled,
@@ -28,6 +29,9 @@ const DesktopAutoOidcOnFirstOpen = memo(() => {
28
29
  useEffect(() => {
29
30
  if (!isInitRemoteServerConfig) return;
30
31
 
32
+ // Don't auto-trigger during onboarding flow.
33
+ if (!getDesktopOnboardingCompleted()) return;
34
+
31
35
  // If already connected or not in cloud mode, don't auto-trigger.
32
36
  if (dataSyncConfig.active) return;
33
37
  if (dataSyncConfig.storageMode !== 'cloud') return;
@@ -19,7 +19,7 @@ const PublishResultModal = memo<PublishResultModalProps>(({ identifier, onCancel
19
19
 
20
20
  const handleGoToMarket = () => {
21
21
  if (identifier) {
22
- navigate(`/community/assistant/${identifier}`);
22
+ navigate(`/community/agent/${identifier}`);
23
23
  }
24
24
  onCancel();
25
25
  };
@@ -18,11 +18,23 @@ const Header = memo(() => {
18
18
  const navigate = useNavigate();
19
19
 
20
20
  const handleGoBack = () => {
21
- // Extract the path segment (assistant, model, provider, mcp)
21
+ // Extract the path segment (agent, model, provider, mcp, group_agent, user)
22
22
  const path = location.pathname.split('/').filter(Boolean);
23
- if (path[1] && path[1] !== 'user') {
24
- navigate(urlJoin('/community', path[1]));
23
+ const detailType = path[1];
24
+
25
+ // group_agent goes back to agent list page
26
+ if (detailType === 'group_agent') {
27
+ navigate('/community/agent');
28
+ return;
29
+ }
30
+
31
+ // Types that have their own list pages
32
+ const typesWithListPage = ['agent', 'model', 'provider', 'mcp'];
33
+
34
+ if (detailType && typesWithListPage.includes(detailType)) {
35
+ navigate(urlJoin('/community', detailType));
25
36
  } else {
37
+ // For user or any other type without a list page
26
38
  navigate('/community');
27
39
  }
28
40
  };
@@ -38,7 +38,7 @@ const TagList = memo<{ tags: string[] }>(({ tags }) => {
38
38
  q: tag,
39
39
  source: marketSource,
40
40
  },
41
- url: '/community/assistant',
41
+ url: '/community/agent',
42
42
  },
43
43
  { skipNull: true },
44
44
  )}
@@ -6,7 +6,7 @@ import { useTranslation } from 'react-i18next';
6
6
  import { useQuery } from '@/hooks/useQuery';
7
7
  import { type AssistantMarketSource } from '@/types/discover';
8
8
 
9
- import McpList from '../../../../../(list)/assistant/features/List';
9
+ import McpList from '../../../../../(list)/agent/features/List';
10
10
  import Title from '../../../../../features/Title';
11
11
  import { useDetailContext } from '../../DetailProvider';
12
12
 
@@ -25,7 +25,7 @@ const Related = memo(() => {
25
25
  category,
26
26
  source: marketSource,
27
27
  },
28
- url: '/community/assistant',
28
+ url: '/community/agent',
29
29
  },
30
30
  { skipNull: true },
31
31
  )}
@@ -38,7 +38,7 @@ const TagList = memo<{ tags: string[] }>(({ tags }) => {
38
38
  q: tag,
39
39
  source: marketSource,
40
40
  },
41
- url: '/community/assistant',
41
+ url: '/community/agent',
42
42
  },
43
43
  { skipNull: true },
44
44
  )}
@@ -4,7 +4,7 @@ import { MessageCircleHeartIcon, MessageCircleQuestionIcon } from 'lucide-react'
4
4
  import { memo } from 'react';
5
5
  import { useTranslation } from 'react-i18next';
6
6
 
7
- import TokenTag from '../../../../../(list)/assistant/features/List/TokenTag';
7
+ import TokenTag from '../../../../../(list)/agent/features/List/TokenTag';
8
8
  import Title from '../../../../../features/Title';
9
9
  import MarkdownRender from '../../../../features/MakedownRender';
10
10
  import { useDetailContext } from '../../DetailProvider';
@@ -32,7 +32,7 @@ import { useMarketAuth } from '@/layout/AuthProvider/MarketAuth';
32
32
  import { socialService } from '@/services/social';
33
33
  import { formatIntergerNumber } from '@/utils/format';
34
34
 
35
- import { useCategory } from '../../../(list)/assistant/features/Category/useCategory';
35
+ import { useCategory } from '../../../(list)/agent/features/Category/useCategory';
36
36
  import PublishedTime from '../../../../../../../components/PublishedTime';
37
37
  import { useDetailContext } from './DetailProvider';
38
38
 
@@ -142,7 +142,7 @@ const Header = memo<{ mobile?: boolean }>(({ mobile: isMobile }) => {
142
142
  <Link
143
143
  to={qs.stringifyUrl({
144
144
  query: { category: cate?.key },
145
- url: '/community/assistant',
145
+ url: '/community/agent',
146
146
  })}
147
147
  >
148
148
  <Button icon={cate?.icon} size={'middle'} variant={'outlined'}>
@@ -87,7 +87,7 @@ const AddAgent = memo<{ mobile?: boolean }>(({ mobile }) => {
87
87
  event: 'add',
88
88
  identifier,
89
89
  source: location.pathname,
90
- })
90
+ });
91
91
  }
92
92
 
93
93
  if (shouldNavigate) {
@@ -21,7 +21,7 @@ const ActionButton = memo<{ mobile?: boolean }>(({ mobile }) => {
21
21
  desc: description,
22
22
  hashtags: tags,
23
23
  title: title,
24
- url: urlJoin(OFFICIAL_URL, '/community/assistant', identifier as string),
24
+ url: urlJoin(OFFICIAL_URL, '/community/agent', identifier as string),
25
25
  }}
26
26
  />
27
27
  </Flexbox>
@@ -28,7 +28,7 @@ const Related = memo(() => {
28
28
  category,
29
29
  source: marketSource,
30
30
  },
31
- url: '/community/assistant',
31
+ url: '/community/agent',
32
32
  },
33
33
  { skipNull: true },
34
34
  )}
@@ -40,7 +40,7 @@ const Related = memo(() => {
40
40
  const link = qs.stringifyUrl(
41
41
  {
42
42
  query: marketSource ? { source: marketSource } : undefined,
43
- url: urlJoin('/community/assistant', item.identifier),
43
+ url: urlJoin('/community/agent', item.identifier),
44
44
  },
45
45
  { skipNull: true },
46
46
  );
@@ -1,7 +1,7 @@
1
1
  'use client';
2
2
 
3
3
  import { ExclamationCircleOutlined, FolderOpenOutlined } from '@ant-design/icons';
4
- import { FluentEmoji, Text , Button } from '@lobehub/ui';
4
+ import { Button, FluentEmoji, Text } from '@lobehub/ui';
5
5
  import { Result } from 'antd';
6
6
  import { memo } from 'react';
7
7
  import { Trans, useTranslation } from 'react-i18next';
@@ -16,7 +16,7 @@ const StatusPage = memo<StatusPageProps>(({ status }) => {
16
16
  const { t } = useTranslation('discover');
17
17
 
18
18
  const handleBackToMarket = () => {
19
- navigate('/community/assistant');
19
+ navigate('/community/agent');
20
20
  };
21
21
 
22
22
  // 审核中状态
@@ -142,7 +142,7 @@ const UserAgentCard = memo<UserAgentCardProps>(
142
142
  const link = qs.stringifyUrl(
143
143
  {
144
144
  query: { source: 'new' },
145
- url: urlJoin('/community/assistant', identifier),
145
+ url: urlJoin('/community/agent', identifier),
146
146
  },
147
147
  { skipNull: true },
148
148
  );
@@ -150,7 +150,7 @@ const UserAgentCard = memo<UserAgentCardProps>(
150
150
  const isPublished = status === 'published';
151
151
 
152
152
  const handleViewDetail = useCallback(() => {
153
- window.open(urlJoin('/community/assistant', identifier), '_blank');
153
+ window.open(urlJoin('/community/agent', identifier), '_blank');
154
154
  }, [identifier]);
155
155
 
156
156
  const handleEdit = useCallback(async () => {
@@ -96,7 +96,7 @@ const FavoriteAgentCard = memo<FavoriteAgentCardProps>(
96
96
  const link = qs.stringifyUrl(
97
97
  {
98
98
  query: { source: 'new' },
99
- url: urlJoin('/community/assistant', identifier),
99
+ url: urlJoin('/community/agent', identifier),
100
100
  },
101
101
  { skipNull: true },
102
102
  );
@@ -7,7 +7,7 @@ import { useDiscoverStore } from '@/store/discover';
7
7
  import { AssistantSorts, McpSorts } from '@/types/discover';
8
8
 
9
9
  import Title from '../../components/Title';
10
- import AssistantList from '../assistant/features/List';
10
+ import AssistantList from '../agent/features/List';
11
11
  import McpList from '../mcp/features/List';
12
12
  import Loading from './loading';
13
13
 
@@ -32,7 +32,7 @@ const HomePage = memo(() => {
32
32
 
33
33
  return (
34
34
  <>
35
- <Title more={t('home.more')} moreLink={'/community/assistant'}>
35
+ <Title more={t('home.more')} moreLink={'/community/agent'}>
36
36
  {t('home.featuredAssistants')}
37
37
  </Title>
38
38
  <AssistantList data={assistantList.items} rows={4} />
@@ -9,7 +9,7 @@ const Loading = memo(() => {
9
9
 
10
10
  return (
11
11
  <>
12
- <Title more={t('home.more')} moreLink={'/community/assistant'}>
12
+ <Title more={t('home.more')} moreLink={'/community/agent'}>
13
13
  {t('home.featuredAssistants')}
14
14
  </Title>
15
15
  <ListLoading length={8} rows={4} />
@@ -6,7 +6,11 @@ import { memo } from 'react';
6
6
  import { withSuspense } from '@/components/withSuspense';
7
7
  import { useQuery } from '@/hooks/useQuery';
8
8
  import { useDiscoverStore } from '@/store/discover';
9
- import { type AssistantMarketSource, type AssistantQueryParams, DiscoverTab } from '@/types/discover';
9
+ import {
10
+ type AssistantMarketSource,
11
+ type AssistantQueryParams,
12
+ DiscoverTab,
13
+ } from '@/types/discover';
10
14
 
11
15
  import Pagination from '../features/Pagination';
12
16
  import List from './features/List';
@@ -29,7 +29,7 @@ const Category = memo(() => {
29
29
  qs.stringifyUrl(
30
30
  {
31
31
  query: { category: key === AssistantCategory.All ? null : key, q, source },
32
- url: '/community/assistant',
32
+ url: '/community/agent',
33
33
  },
34
34
  { skipNull: true },
35
35
  );
@@ -73,7 +73,7 @@ const AssistantItem = memo<DiscoverAssistantItem>(
73
73
  const navigate = useNavigate();
74
74
  const { source } = useQuery() as { source?: AssistantMarketSource };
75
75
  const isGroupAgent = type === 'agent-group';
76
- const basePath = isGroupAgent ? '/community/group_agent' : '/community/assistant';
76
+ const basePath = isGroupAgent ? '/community/group_agent' : '/community/agent';
77
77
  const link = qs.stringifyUrl(
78
78
  {
79
79
  query: { source },