@lobehub/lobehub 2.0.0-next.220 → 2.0.0-next.222

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 (123) hide show
  1. package/.github/workflows/claude-auto-testing.yml +6 -3
  2. package/.github/workflows/claude-dedupe-issues.yml +8 -1
  3. package/.github/workflows/claude-issue-triage.yml +8 -14
  4. package/.github/workflows/claude-translate-comments.yml +6 -3
  5. package/.github/workflows/claude-translator.yml +12 -14
  6. package/.github/workflows/claude.yml +10 -20
  7. package/.github/workflows/test.yml +26 -0
  8. package/.i18nrc.js +4 -2
  9. package/CHANGELOG.md +66 -0
  10. package/apps/desktop/src/main/core/browser/Browser.ts +48 -20
  11. package/apps/desktop/src/main/core/browser/__tests__/Browser.test.ts +1 -0
  12. package/changelog/v1.json +21 -0
  13. package/docs/glossary.md +11 -0
  14. package/locales/zh-CN/components.json +1 -0
  15. package/locales/zh-CN/topic.json +5 -5
  16. package/package.json +3 -3
  17. package/packages/const/src/index.ts +0 -1
  18. package/packages/memory-user-memory/package.json +1 -0
  19. package/packages/memory-user-memory/src/extractors/context.test.ts +3 -2
  20. package/packages/memory-user-memory/src/extractors/experience.test.ts +3 -2
  21. package/packages/memory-user-memory/src/extractors/identity.test.ts +23 -6
  22. package/packages/memory-user-memory/src/extractors/preference.test.ts +3 -2
  23. package/packages/memory-user-memory/vitest.config.ts +4 -0
  24. package/packages/model-runtime/src/providers/replicate/index.ts +1 -1
  25. package/packages/ssrf-safe-fetch/index.test.ts +2 -2
  26. package/packages/ssrf-safe-fetch/package.json +3 -2
  27. package/packages/types/src/serverConfig.ts +2 -0
  28. package/packages/utils/package.json +1 -1
  29. package/packages/utils/src/client/xor-obfuscation.test.ts +32 -32
  30. package/packages/utils/src/client/xor-obfuscation.ts +3 -4
  31. package/packages/utils/src/imageToBase64.ts +1 -1
  32. package/packages/utils/src/server/__tests__/auth.test.ts +1 -1
  33. package/packages/utils/src/server/auth.ts +1 -1
  34. package/packages/utils/src/server/xor.test.ts +9 -7
  35. package/packages/utils/src/server/xor.ts +1 -1
  36. package/packages/web-crawler/package.json +1 -1
  37. package/packages/web-crawler/src/crawImpl/__tests__/naive.test.ts +1 -1
  38. package/packages/web-crawler/src/crawImpl/naive.ts +1 -1
  39. package/scripts/prebuild.mts +58 -1
  40. package/src/app/(backend)/api/auth/[...all]/route.ts +2 -1
  41. package/src/app/(backend)/middleware/auth/index.ts +3 -3
  42. package/src/app/(backend)/middleware/auth/utils.test.ts +1 -1
  43. package/src/app/(backend)/middleware/auth/utils.ts +1 -1
  44. package/src/app/(backend)/webapi/chat/[provider]/route.test.ts +2 -2
  45. package/src/app/(backend)/webapi/models/[provider]/route.test.ts +1 -1
  46. package/src/app/(backend)/webapi/plugin/gateway/route.ts +1 -1
  47. package/src/app/(backend)/webapi/proxy/route.ts +1 -1
  48. package/src/app/[variants]/(auth)/login/[[...login]]/page.tsx +1 -1
  49. package/src/app/[variants]/(auth)/reset-password/layout.tsx +1 -1
  50. package/src/app/[variants]/(auth)/signin/layout.tsx +1 -1
  51. package/src/app/[variants]/(auth)/signin/useSignIn.ts +2 -2
  52. package/src/app/[variants]/(auth)/signup/[[...signup]]/page.tsx +1 -1
  53. package/src/app/[variants]/(auth)/signup/[[...signup]]/useSignUp.tsx +12 -6
  54. package/src/app/[variants]/(auth)/verify-email/layout.tsx +1 -1
  55. package/src/app/[variants]/(main)/settings/profile/features/AvatarRow.tsx +1 -1
  56. package/src/app/[variants]/(main)/settings/security/index.tsx +1 -1
  57. package/src/app/[variants]/(mobile)/me/(home)/__tests__/UserBanner.test.tsx +1 -1
  58. package/src/app/[variants]/(mobile)/me/(home)/__tests__/useCategory.test.tsx +1 -1
  59. package/src/app/[variants]/(mobile)/me/(home)/features/UserBanner.tsx +1 -1
  60. package/src/app/[variants]/(mobile)/settings/_layout/Header.tsx +1 -1
  61. package/src/components/ModelSelect/index.tsx +103 -72
  62. package/src/envs/auth.ts +30 -9
  63. package/src/features/Conversation/Messages/AssistantGroup/components/EditState.tsx +15 -32
  64. package/src/features/Conversation/Messages/AssistantGroup/index.tsx +9 -7
  65. package/src/features/EditorModal/EditorCanvas.tsx +31 -50
  66. package/src/features/EditorModal/TextareCanvas.tsx +3 -1
  67. package/src/features/EditorModal/index.tsx +14 -4
  68. package/src/features/ModelSwitchPanel/components/Footer.tsx +42 -0
  69. package/src/features/ModelSwitchPanel/components/List/MultipleProvidersModelItem.tsx +103 -0
  70. package/src/features/ModelSwitchPanel/components/List/SingleProviderModelItem.tsx +24 -0
  71. package/src/features/ModelSwitchPanel/components/List/VirtualItemRenderer.tsx +180 -0
  72. package/src/features/ModelSwitchPanel/components/List/index.tsx +99 -0
  73. package/src/features/ModelSwitchPanel/components/PanelContent.tsx +77 -0
  74. package/src/features/ModelSwitchPanel/components/Toolbar.tsx +54 -0
  75. package/src/features/ModelSwitchPanel/const.ts +29 -0
  76. package/src/features/ModelSwitchPanel/hooks/useBuildVirtualItems.ts +122 -0
  77. package/src/features/ModelSwitchPanel/hooks/useCurrentModelName.ts +18 -0
  78. package/src/features/ModelSwitchPanel/hooks/useDelayedRender.ts +18 -0
  79. package/src/features/ModelSwitchPanel/hooks/useModelAndProvider.ts +14 -0
  80. package/src/features/ModelSwitchPanel/hooks/usePanelHandlers.ts +33 -0
  81. package/src/features/ModelSwitchPanel/hooks/usePanelSize.ts +33 -0
  82. package/src/features/ModelSwitchPanel/hooks/usePanelState.ts +20 -0
  83. package/src/features/ModelSwitchPanel/index.tsx +25 -706
  84. package/src/features/ModelSwitchPanel/styles.ts +58 -0
  85. package/src/features/ModelSwitchPanel/types.ts +73 -0
  86. package/src/features/ModelSwitchPanel/utils.ts +24 -0
  87. package/src/features/User/UserPanel/PanelContent.tsx +1 -1
  88. package/src/features/User/__tests__/PanelContent.test.tsx +1 -1
  89. package/src/features/User/__tests__/UserAvatar.test.tsx +1 -1
  90. package/src/features/User/__tests__/useMenu.test.tsx +1 -1
  91. package/src/layout/GlobalProvider/StoreInitialization.tsx +2 -1
  92. package/src/libs/better-auth/auth-client.ts +7 -3
  93. package/src/libs/better-auth/define-config.ts +2 -2
  94. package/src/libs/next/proxy/define-config.ts +1 -2
  95. package/src/libs/oidc-provider/provider.test.ts +1 -1
  96. package/src/libs/trpc/async/context.ts +1 -1
  97. package/src/libs/trpc/lambda/context.ts +7 -8
  98. package/src/libs/trpc/middleware/userAuth.ts +1 -1
  99. package/src/libs/trusted-client/getSessionUser.ts +1 -1
  100. package/src/locales/default/components.ts +1 -0
  101. package/src/server/globalConfig/index.ts +2 -0
  102. package/src/server/routers/async/caller.ts +1 -1
  103. package/src/server/routers/lambda/__tests__/user.test.ts +2 -2
  104. package/src/server/routers/lambda/notebook.ts +4 -2
  105. package/src/server/routers/lambda/user.ts +2 -1
  106. package/src/services/_auth.ts +3 -3
  107. package/src/services/chat/index.ts +1 -1
  108. package/src/services/chat/mecha/contextEngineering.ts +1 -1
  109. package/src/services/notebook.ts +2 -0
  110. package/src/store/global/initialState.ts +10 -0
  111. package/src/store/global/selectors/systemStatus.ts +5 -0
  112. package/src/store/serverConfig/selectors.ts +5 -1
  113. package/src/store/tool/slices/builtin/executors/lobe-web-browsing.ts +2 -0
  114. package/src/store/tool/slices/mcpStore/action.ts +74 -75
  115. package/src/store/user/slices/auth/action.test.ts +1 -1
  116. package/src/store/user/slices/auth/action.ts +1 -1
  117. package/src/store/user/slices/auth/initialState.ts +1 -1
  118. package/src/store/user/slices/auth/selectors.test.ts +1 -1
  119. package/src/store/user/slices/auth/selectors.ts +1 -1
  120. package/src/store/user/slices/common/action.ts +1 -1
  121. package/src/store/userMemory/slices/context/action.ts +6 -6
  122. package/glossary.json +0 -8
  123. package/packages/const/src/auth.ts +0 -14
@@ -67,7 +67,6 @@ const toNonEmptyStringRecord = (input?: Record<string, any>) => {
67
67
 
68
68
  /**
69
69
  * Build manifest for cloud MCP connection from market data
70
- * 从市场数据构建 Cloud MCP 的 manifest
71
70
  */
72
71
  const buildCloudMcpManifest = (params: {
73
72
  data: any;
@@ -77,21 +76,21 @@ const buildCloudMcpManifest = (params: {
77
76
 
78
77
  log('Using cloud connection, building manifest from market data');
79
78
 
80
- // data 中获取 tools(MCP 格式)或 apiLobeChat 格式)
79
+ // Get tools (MCP format) or api (LobeChat format) from data
81
80
  const mcpTools = data.tools;
82
81
  const lobeChatApi = data.api;
83
82
 
84
- // 如果是 MCP 格式的 tools,需要转换为 LobeChat api 格式
83
+ // If MCP format tools, need to convert to LobeChat api format
85
84
  // MCP: { name, description, inputSchema }
86
85
  // LobeChat: { name, description, parameters }
87
86
  let apiArray: any[] = [];
88
87
 
89
88
  if (lobeChatApi) {
90
- // 已经是 LobeChat 格式,直接使用
89
+ // Already in LobeChat format, use directly
91
90
  apiArray = lobeChatApi;
92
91
  log('[Cloud MCP] Using existing LobeChat API format');
93
92
  } else if (mcpTools && Array.isArray(mcpTools)) {
94
- // 转换 MCP tools 格式到 LobeChat api 格式
93
+ // Convert MCP tools format to LobeChat api format
95
94
  apiArray = mcpTools.map((tool: any) => ({
96
95
  description: tool.description || '',
97
96
  name: tool.name,
@@ -102,7 +101,7 @@ const buildCloudMcpManifest = (params: {
102
101
  console.warn('[Cloud MCP] No tools or api found in manifest data');
103
102
  }
104
103
 
105
- // 构建完整的 manifest
104
+ // Build complete manifest
106
105
  const manifest: LobeChatPluginManifest = {
107
106
  api: apiArray,
108
107
  author: data.author?.name || data.author || '',
@@ -130,7 +129,7 @@ const buildCloudMcpManifest = (params: {
130
129
  return manifest;
131
130
  };
132
131
 
133
- // 测试连接结果类型
132
+ // Test connection result type
134
133
  export interface TestMcpConnectionResult {
135
134
  error?: string;
136
135
  manifest?: LobeChatPluginManifest;
@@ -146,7 +145,7 @@ export interface PluginMCPStoreAction {
146
145
  ) => Promise<boolean | undefined>;
147
146
  loadMoreMCPPlugins: () => void;
148
147
  resetMCPPluginList: (keywords?: string) => void;
149
- // 测试连接相关方法
148
+ // Test connection related methods
150
149
  testMcpConnection: (params: McpConnectionParams) => Promise<TestMcpConnectionResult>;
151
150
  uninstallMCPPlugin: (identifier: string) => Promise<void>;
152
151
  updateMCPInstallProgress: (identifier: string, progress: MCPInstallProgress | undefined) => void;
@@ -160,12 +159,12 @@ export const createMCPPluginStoreSlice: StateCreator<
160
159
  PluginMCPStoreAction
161
160
  > = (set, get) => ({
162
161
  cancelInstallMCPPlugin: async (identifier) => {
163
- // 获取并取消AbortController
162
+ // Get and cancel AbortController
164
163
  const abortController = get().mcpInstallAbortControllers[identifier];
165
164
  if (abortController) {
166
165
  abortController.abort();
167
166
 
168
- // 清理AbortController存储
167
+ // Clean up AbortController storage
169
168
  set(
170
169
  produce((draft: MCPStoreState) => {
171
170
  delete draft.mcpInstallAbortControllers[identifier];
@@ -175,18 +174,18 @@ export const createMCPPluginStoreSlice: StateCreator<
175
174
  );
176
175
  }
177
176
 
178
- // 清理安装进度和加载状态
177
+ // Clean up installation progress and loading state
179
178
  get().updateMCPInstallProgress(identifier, undefined);
180
179
  get().updateInstallLoadingState(identifier, undefined);
181
180
  },
182
181
 
183
- // 取消 MCP 连接测试
182
+ // Cancel MCP connection test
184
183
  cancelMcpConnectionTest: (identifier) => {
185
184
  const abortController = get().mcpTestAbortControllers[identifier];
186
185
  if (abortController) {
187
186
  abortController.abort();
188
187
 
189
- // 清理状态
188
+ // Clean up state
190
189
  set(
191
190
  produce((draft: MCPStoreState) => {
192
191
  draft.mcpTestLoading[identifier] = false;
@@ -218,10 +217,10 @@ export const createMCPPluginStoreSlice: StateCreator<
218
217
 
219
218
  const { updateInstallLoadingState, refreshPlugins, updateMCPInstallProgress } = get();
220
219
 
221
- // 创建AbortController用于取消安装
220
+ // Create AbortController for canceling installation
222
221
  const abortController = new AbortController();
223
222
 
224
- // 存储AbortController
223
+ // Store AbortController
225
224
  set(
226
225
  produce((draft: MCPStoreState) => {
227
226
  draft.mcpInstallAbortControllers[identifier] = abortController;
@@ -230,7 +229,7 @@ export const createMCPPluginStoreSlice: StateCreator<
230
229
  n('installMCPPlugin/setController'),
231
230
  );
232
231
 
233
- // 记录安装开始时间
232
+ // Record installation start time
234
233
  const installStartTime = Date.now();
235
234
 
236
235
  let data: any;
@@ -239,13 +238,13 @@ export const createMCPPluginStoreSlice: StateCreator<
239
238
  const userAgent = `LobeHub Desktop/${CURRENT_VERSION}`;
240
239
 
241
240
  try {
242
- // 检查是否已被取消
241
+ // Check if already cancelled
243
242
  if (abortController.signal.aborted) {
244
243
  return;
245
244
  }
246
245
 
247
246
  if (resume) {
248
- // 恢复模式:从存储中获取之前的信息
247
+ // Resume mode: get previous info from storage
249
248
  const configInfo = get().mcpInstallProgress[identifier];
250
249
  if (!configInfo) {
251
250
  console.error('No config info found for resume');
@@ -256,9 +255,9 @@ export const createMCPPluginStoreSlice: StateCreator<
256
255
  connection = configInfo.connection ? { ...configInfo.connection } : undefined;
257
256
  result = configInfo.checkResult;
258
257
  } else {
259
- // 正常模式:从头开始安装
258
+ // Normal mode: start installation from scratch
260
259
 
261
- // 步骤 1: 获取插件清单
260
+ // Step 1: Fetch plugin manifest
262
261
  updateMCPInstallProgress(identifier, {
263
262
  progress: 15,
264
263
  step: MCPInstallStep.FETCHING_MANIFEST,
@@ -266,7 +265,7 @@ export const createMCPPluginStoreSlice: StateCreator<
266
265
 
267
266
  updateInstallLoadingState(identifier, true);
268
267
 
269
- // 检查是否已被取消
268
+ // Check if already cancelled
270
269
  if (abortController.signal.aborted) {
271
270
  return;
272
271
  }
@@ -285,7 +284,7 @@ export const createMCPPluginStoreSlice: StateCreator<
285
284
  ) ||
286
285
  deploymentOptions.find((option) => option?.connection?.url && !option?.connection?.type);
287
286
 
288
- // 查找 stdio 类型的部署选项
287
+ // Find stdio type deployment option
289
288
  const stdioOption = deploymentOptions.find(
290
289
  (option) =>
291
290
  option?.connection?.type === 'stdio' ||
@@ -299,7 +298,7 @@ export const createMCPPluginStoreSlice: StateCreator<
299
298
  return type && type !== 'http';
300
299
  });
301
300
 
302
- // 🌐 检查是否有 cloudEndPoint:网页端 + stdio 类型 + 存在 haveCloudEndpoint
301
+ // Check if cloudEndPoint is available: web + stdio type + haveCloudEndpoint exists
303
302
  const hasCloudEndpoint = !isDesktop && stdioOption && haveCloudEndpoint;
304
303
 
305
304
  console.log('hasCloudEndpoint', hasCloudEndpoint);
@@ -307,7 +306,7 @@ export const createMCPPluginStoreSlice: StateCreator<
307
306
  let shouldUseHttpDeployment = !!httpOption && (!hasNonHttpDeployment || !isDesktop);
308
307
 
309
308
  if (hasCloudEndpoint) {
310
- // 🌐 使用 cloudEndPoint,创建 cloud 类型的 connection
309
+ // Use cloudEndPoint, create cloud type connection
311
310
  log('Using cloudEndPoint for stdio plugin: %s', haveCloudEndpoint);
312
311
 
313
312
  connection = {
@@ -339,7 +338,7 @@ export const createMCPPluginStoreSlice: StateCreator<
339
338
  return false;
340
339
  }
341
340
  } else if (shouldUseHttpDeployment && httpOption) {
342
- // HTTP 类型:跳过系统依赖检查,直接使用 URL
341
+ // HTTP type: skip system dependency check, use URL directly
343
342
  log('HTTP MCP detected, skipping system dependency check');
344
343
 
345
344
  connection = {
@@ -368,15 +367,15 @@ export const createMCPPluginStoreSlice: StateCreator<
368
367
  return false;
369
368
  }
370
369
  } else {
371
- // stdio 类型:需要完整的系统依赖检查流程
370
+ // stdio type: requires complete system dependency check process
372
371
 
373
- // 步骤 2: 检查安装环境
372
+ // Step 2: Check installation environment
374
373
  updateMCPInstallProgress(identifier, {
375
374
  progress: 30,
376
375
  step: MCPInstallStep.CHECKING_INSTALLATION,
377
376
  });
378
377
 
379
- // 检查是否已被取消
378
+ // Check if already cancelled
380
379
  if (abortController.signal.aborted) {
381
380
  return;
382
381
  }
@@ -388,9 +387,9 @@ export const createMCPPluginStoreSlice: StateCreator<
388
387
  return;
389
388
  }
390
389
 
391
- // 步骤 3: 检查系统依赖是否满足
390
+ // Step 3: Check if system dependencies are met
392
391
  if (!skipDepsCheck && !result.allDependenciesMet) {
393
- // 依赖不满足,暂停安装流程并显示依赖安装引导
392
+ // Dependencies not met, pause installation and show dependency installation guide
394
393
  updateMCPInstallProgress(identifier, {
395
394
  connection: result.connection,
396
395
  manifest: data,
@@ -399,14 +398,14 @@ export const createMCPPluginStoreSlice: StateCreator<
399
398
  systemDependencies: result.systemDependencies,
400
399
  });
401
400
 
402
- // 暂停安装流程,等待用户安装依赖
401
+ // Pause installation, wait for user to install dependencies
403
402
  updateInstallLoadingState(identifier, undefined);
404
- return false; // 返回 false 表示需要安装依赖
403
+ return false; // Return false to indicate dependencies need to be installed
405
404
  }
406
405
 
407
- // 步骤 4: 检查是否需要配置
406
+ // Step 4: Check if configuration is needed
408
407
  if (result.needsConfig) {
409
- // 需要配置,暂停安装流程
408
+ // Configuration needed, pause installation
410
409
  updateMCPInstallProgress(identifier, {
411
410
  checkResult: result,
412
411
  configSchema: result.configSchema,
@@ -417,9 +416,9 @@ export const createMCPPluginStoreSlice: StateCreator<
417
416
  step: MCPInstallStep.CONFIGURATION_REQUIRED,
418
417
  });
419
418
 
420
- // 暂停安装流程,等待用户配置
419
+ // Pause installation, wait for user configuration
421
420
  updateInstallLoadingState(identifier, undefined);
422
- return false; // 返回 false 表示需要配置
421
+ return false; // Return false to indicate configuration is needed
423
422
  }
424
423
 
425
424
  connection = result.connection;
@@ -463,16 +462,16 @@ export const createMCPPluginStoreSlice: StateCreator<
463
462
  }
464
463
  }
465
464
 
466
- // 获取服务器清单逻辑
465
+ // Get server manifest logic
467
466
  updateInstallLoadingState(identifier, true);
468
467
 
469
- // 步骤 5: 获取服务器清单
468
+ // Step 5: Get server manifest
470
469
  updateMCPInstallProgress(identifier, {
471
470
  progress: 70,
472
471
  step: MCPInstallStep.GETTING_SERVER_MANIFEST,
473
472
  });
474
473
 
475
- // 检查是否已被取消
474
+ // Check if already cancelled
476
475
  if (abortController.signal.aborted) {
477
476
  return;
478
477
  }
@@ -485,7 +484,7 @@ export const createMCPPluginStoreSlice: StateCreator<
485
484
  args: connection.args,
486
485
  command: connection.command!,
487
486
  env: mergedStdioEnv,
488
- name: identifier, // 将配置作为环境变量传递(resume 模式下)
487
+ name: identifier, // Pass config as environment variables (in resume mode)
489
488
  },
490
489
  { avatar: plugin.icon, description: plugin.description, name: data.name },
491
490
  abortController.signal,
@@ -507,31 +506,31 @@ export const createMCPPluginStoreSlice: StateCreator<
507
506
  );
508
507
  }
509
508
  if (connection?.type === 'cloud') {
510
- // 🌐 Cloud 类型:直接从市场数据构建 manifest
509
+ // Cloud type: build manifest directly from market data
511
510
  manifest = buildCloudMcpManifest({ data, plugin });
512
511
  }
513
512
 
514
513
  // set version
515
514
  if (manifest) {
516
- // set Version - 使用 semver 比较版本号并取更大的值
515
+ // set Version - use semver to compare versions and take the larger value
517
516
  const dataVersion = data?.version;
518
517
  const manifestVersion = manifest.version;
519
518
 
520
519
  if (dataVersion && manifestVersion) {
521
- // 如果两个版本都存在,比较并取更大的值
520
+ // If both versions exist, compare and take the larger value
522
521
  if (valid(dataVersion) && valid(manifestVersion)) {
523
522
  manifest.version = gt(dataVersion, manifestVersion) ? dataVersion : manifestVersion;
524
523
  } else {
525
- // 如果版本号格式不正确,优先使用 dataVersion
524
+ // If version format is incorrect, prioritize dataVersion
526
525
  manifest.version = dataVersion;
527
526
  }
528
527
  } else {
529
- // 如果只有一个版本存在,使用存在的版本
528
+ // If only one version exists, use the existing version
530
529
  manifest.version = dataVersion || manifestVersion;
531
530
  }
532
531
  }
533
532
 
534
- // 检查是否已被取消
533
+ // Check if already cancelled
535
534
  if (abortController.signal.aborted) {
536
535
  return;
537
536
  }
@@ -541,18 +540,18 @@ export const createMCPPluginStoreSlice: StateCreator<
541
540
  return;
542
541
  }
543
542
 
544
- // 步骤 6: 安装插件
543
+ // Step 6: Install plugin
545
544
  updateMCPInstallProgress(identifier, {
546
545
  progress: 90,
547
546
  step: MCPInstallStep.INSTALLING_PLUGIN,
548
547
  });
549
548
 
550
- // 检查是否已被取消
549
+ // Check if already cancelled
551
550
  if (abortController.signal.aborted) {
552
551
  return;
553
552
  }
554
553
 
555
- // 更新 connection 对象,将合并后的配置写入
554
+ // Update connection object, write merged configuration
556
555
  const finalConnection = { ...connection };
557
556
  if (finalConnection.type === 'http' && mergedHttpHeaders) {
558
557
  finalConnection.headers = mergedHttpHeaders;
@@ -565,7 +564,7 @@ export const createMCPPluginStoreSlice: StateCreator<
565
564
  }
566
565
 
567
566
  await pluginService.installPlugin({
568
- // 针对 mcp 先将 connection 信息存到 customParams 字段里
567
+ // For mcp, store connection info in customParams field first
569
568
  customParams: { mcp: finalConnection },
570
569
  identifier: plugin.identifier,
571
570
  manifest: manifest,
@@ -573,20 +572,20 @@ export const createMCPPluginStoreSlice: StateCreator<
573
572
  type: 'plugin',
574
573
  });
575
574
 
576
- // 检查是否已被取消
575
+ // Check if already cancelled
577
576
  if (abortController.signal.aborted) {
578
577
  return;
579
578
  }
580
579
 
581
580
  await refreshPlugins();
582
581
 
583
- // 步骤 7: 完成安装
582
+ // Step 7: Complete installation
584
583
  updateMCPInstallProgress(identifier, {
585
584
  progress: 100,
586
585
  step: MCPInstallStep.COMPLETED,
587
586
  });
588
587
 
589
- // 计算安装持续时间
588
+ // Calculate installation duration
590
589
  const installDurationMs = Date.now() - installStartTime;
591
590
 
592
591
  discoverService.reportMcpInstallResult({
@@ -604,13 +603,13 @@ export const createMCPPluginStoreSlice: StateCreator<
604
603
  version: manifest.version || data.version,
605
604
  });
606
605
 
607
- // 短暂显示完成状态后清除进度
606
+ // Show completed status briefly then clear progress
608
607
  await sleep(1000);
609
608
 
610
609
  updateMCPInstallProgress(identifier, undefined);
611
610
  updateInstallLoadingState(identifier, undefined);
612
611
 
613
- // 清理AbortController
612
+ // Clean up AbortController
614
613
  set(
615
614
  produce((draft: MCPStoreState) => {
616
615
  delete draft.mcpInstallAbortControllers[identifier];
@@ -621,7 +620,7 @@ export const createMCPPluginStoreSlice: StateCreator<
621
620
 
622
621
  return true;
623
622
  } catch (e) {
624
- // 如果是因为取消导致的错误,静默处理
623
+ // Silently handle errors caused by cancellation
625
624
  if (abortController.signal.aborted) {
626
625
  console.log('MCP plugin installation cancelled for:', identifier);
627
626
  return;
@@ -631,13 +630,13 @@ export const createMCPPluginStoreSlice: StateCreator<
631
630
 
632
631
  console.error('MCP plugin installation failed:', error);
633
632
 
634
- // 计算安装持续时间(失败情况)
633
+ // Calculate installation duration (failure case)
635
634
  const installDurationMs = Date.now() - installStartTime;
636
635
 
637
- // 处理结构化错误信息
636
+ // Handle structured error info
638
637
  let errorInfo: MCPErrorInfo;
639
638
 
640
- // 如果是结构化的 MCPError
639
+ // If it's a structured MCPError
641
640
  if (!!error.data && 'errorData' in error.data) {
642
641
  const mcpError = error.data.errorData as MCPErrorData;
643
642
 
@@ -647,7 +646,7 @@ export const createMCPPluginStoreSlice: StateCreator<
647
646
  type: mcpError.type,
648
647
  };
649
648
  } else {
650
- // 兜底处理普通错误
649
+ // Fallback handling for normal errors
651
650
  const errorMessage = error instanceof Error ? error.message : String(error);
652
651
  errorInfo = {
653
652
  message: errorMessage,
@@ -659,14 +658,14 @@ export const createMCPPluginStoreSlice: StateCreator<
659
658
  };
660
659
  }
661
660
 
662
- // 设置错误状态,显示结构化错误信息
661
+ // Set error status, display structured error info
663
662
  updateMCPInstallProgress(identifier, {
664
663
  errorInfo,
665
664
  progress: 0,
666
665
  step: MCPInstallStep.ERROR,
667
666
  });
668
667
 
669
- // 上报安装失败结果
668
+ // Report installation failure result
670
669
  discoverService.reportMcpInstallResult({
671
670
  errorCode: errorInfo.type,
672
671
  errorMessage: errorInfo.message,
@@ -682,7 +681,7 @@ export const createMCPPluginStoreSlice: StateCreator<
682
681
 
683
682
  updateInstallLoadingState(identifier, undefined);
684
683
 
685
- // 清理AbortController
684
+ // Clean up AbortController
686
685
  set(
687
686
  produce((draft: MCPStoreState) => {
688
687
  delete draft.mcpInstallAbortControllers[identifier];
@@ -696,7 +695,7 @@ export const createMCPPluginStoreSlice: StateCreator<
696
695
  loadMoreMCPPlugins: () => {
697
696
  const { mcpPluginItems, totalCount, currentPage } = get();
698
697
 
699
- // 检查是否还有更多数据可以加载
698
+ // Check if there's more data to load
700
699
  if (mcpPluginItems.length < (totalCount || 0)) {
701
700
  set(
702
701
  produce((draft: MCPStoreState) => {
@@ -720,14 +719,14 @@ export const createMCPPluginStoreSlice: StateCreator<
720
719
  );
721
720
  },
722
721
 
723
- // 测试 MCP 连接
722
+ // Test MCP connection
724
723
  testMcpConnection: async (params) => {
725
724
  const { identifier, connection, metadata } = params;
726
725
 
727
- // 创建 AbortController 用于取消测试
726
+ // Create AbortController for canceling test
728
727
  const abortController = new AbortController();
729
728
 
730
- // 存储 AbortController 并设置加载状态
729
+ // Store AbortController and set loading state
731
730
  set(
732
731
  produce((draft: MCPStoreState) => {
733
732
  draft.mcpTestAbortControllers[identifier] = abortController;
@@ -775,12 +774,12 @@ export const createMCPPluginStoreSlice: StateCreator<
775
774
  throw new Error('Invalid MCP connection type');
776
775
  }
777
776
 
778
- // 检查是否已被取消
777
+ // Check if already cancelled
779
778
  if (abortController.signal.aborted) {
780
779
  return { error: 'Test cancelled', success: false };
781
780
  }
782
781
 
783
- // 清理状态
782
+ // Clean up state
784
783
  set(
785
784
  produce((draft: MCPStoreState) => {
786
785
  draft.mcpTestLoading[identifier] = false;
@@ -793,14 +792,14 @@ export const createMCPPluginStoreSlice: StateCreator<
793
792
 
794
793
  return { manifest, success: true };
795
794
  } catch (error) {
796
- // 如果是因为取消导致的错误,静默处理
795
+ // Silently handle errors caused by cancellation
797
796
  if (abortController.signal.aborted) {
798
797
  return { error: 'Test cancelled', success: false };
799
798
  }
800
799
 
801
800
  const errorMessage = error instanceof Error ? error.message : String(error);
802
801
 
803
- // 设置错误状态
802
+ // Set error state
804
803
  set(
805
804
  produce((draft: MCPStoreState) => {
806
805
  draft.mcpTestLoading[identifier] = false;
@@ -857,7 +856,7 @@ export const createMCPPluginStoreSlice: StateCreator<
857
856
  produce((draft: MCPStoreState) => {
858
857
  draft.searchLoading = false;
859
858
 
860
- // 设置基础信息
859
+ // Set basic information
861
860
  if (!draft.isMcpListInit) {
862
861
  draft.activeMCPIdentifier = data.items?.[0]?.identifier;
863
862
 
@@ -867,12 +866,12 @@ export const createMCPPluginStoreSlice: StateCreator<
867
866
  draft.totalPages = data.totalPages;
868
867
  }
869
868
 
870
- // 累积数据逻辑
869
+ // Accumulate data logic
871
870
  if (page === 1) {
872
- // 第一页,直接设置
871
+ // First page, set directly
873
872
  draft.mcpPluginItems = uniqBy(data.items, 'identifier');
874
873
  } else {
875
- // 后续页面,累积数据
874
+ // Subsequent pages, accumulate data
876
875
  draft.mcpPluginItems = uniqBy(
877
876
  [...draft.mcpPluginItems, ...data.items],
878
877
  'identifier',
@@ -23,7 +23,7 @@ const { enableClerk, enableNextAuth, enableBetterAuth, enableAuth } = vi.hoisted
23
23
  enableAuth: { value: true },
24
24
  }));
25
25
 
26
- vi.mock('@/const/auth', () => ({
26
+ vi.mock('@/envs/auth', () => ({
27
27
  get enableClerk() {
28
28
  return enableClerk.value;
29
29
  },
@@ -1,7 +1,7 @@
1
1
  import { type SSOProvider } from '@lobechat/types';
2
2
  import { type StateCreator } from 'zustand/vanilla';
3
3
 
4
- import { enableAuth, enableBetterAuth, enableClerk, enableNextAuth } from '@/const/auth';
4
+ import { enableAuth, enableBetterAuth, enableClerk, enableNextAuth } from '@/envs/auth';
5
5
  import { userService } from '@/services/user';
6
6
 
7
7
  import type { UserStore } from '../../store';
@@ -8,7 +8,7 @@ import {
8
8
  } from '@clerk/types';
9
9
  import { type SSOProvider } from '@lobechat/types';
10
10
 
11
- import { enableClerk } from '@/const/auth';
11
+ import { enableClerk } from '@/envs/auth';
12
12
  import { type LobeUser } from '@/types/user';
13
13
 
14
14
  export interface UserAuthState {
@@ -15,7 +15,7 @@ let enableAuth = true;
15
15
  let isDesktop = false;
16
16
 
17
17
  // 模拟 @/const/auth 模块
18
- vi.mock('@/const/auth', () => ({
18
+ vi.mock('@/envs/auth', () => ({
19
19
  get enableAuth() {
20
20
  return enableAuth;
21
21
  },
@@ -3,7 +3,7 @@ import { isDesktop } from '@lobechat/const';
3
3
  import { type LobeUser, type SSOProvider } from '@lobechat/types';
4
4
  import { t } from 'i18next';
5
5
 
6
- import { enableAuth, enableBetterAuth, enableClerk, enableNextAuth } from '@/const/auth';
6
+ import { enableAuth, enableBetterAuth, enableClerk, enableNextAuth } from '@/envs/auth';
7
7
  import type { UserStore } from '@/store/user';
8
8
 
9
9
  const DEFAULT_USERNAME = BRANDING_NAME;
@@ -20,7 +20,7 @@ const n = setNamespace('common');
20
20
 
21
21
  const GET_USER_STATE_KEY = 'initUserState';
22
22
  /**
23
- * 设置操作
23
+ * Common actions
24
24
  */
25
25
  export interface CommonAction {
26
26
  refreshUserState: () => Promise<void>;
@@ -91,29 +91,29 @@ export const createContextSlice: StateCreator<
91
91
  produce((draft) => {
92
92
  draft.contextsSearchLoading = false;
93
93
 
94
- // 设置基础信息
94
+ // Set basic information
95
95
  if (!draft.contextsInit) {
96
96
  draft.contextsInit = true;
97
97
  draft.contextsTotal = data.total;
98
98
  }
99
99
 
100
- // 转换数据结构
100
+ // Transform data structure
101
101
  const transformedItems = data.items.map((item: any) => ({
102
102
  ...item.memory,
103
103
  ...item.context,
104
104
  source: null,
105
105
  }));
106
106
 
107
- // 累积数据逻辑
107
+ // Accumulate data logic
108
108
  if (page === 1) {
109
- // 第一页,直接设置
109
+ // First page, set directly
110
110
  draft.contexts = uniqBy(transformedItems, 'id');
111
111
  } else {
112
- // 后续页面,累积数据
112
+ // Subsequent pages, accumulate data
113
113
  draft.contexts = uniqBy([...draft.contexts, ...transformedItems], 'id');
114
114
  }
115
115
 
116
- // 更新 hasMore
116
+ // Update hasMore
117
117
  draft.contextsHasMore = data.items.length >= (params.pageSize || 20);
118
118
  }),
119
119
  false,
package/glossary.json DELETED
@@ -1,8 +0,0 @@
1
- {
2
- "助理": {
3
- "en-US": "Agent"
4
- },
5
- "文稿": {
6
- "en-US": "Page"
7
- }
8
- }
@@ -1,14 +0,0 @@
1
- export const enableClerk =
2
- process.env.NEXT_PUBLIC_ENABLE_CLERK_AUTH === '1'
3
- ? true
4
- : !!process.env.NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY;
5
- export const enableBetterAuth = process.env.NEXT_PUBLIC_ENABLE_BETTER_AUTH === '1';
6
- export const enableNextAuth = process.env.NEXT_PUBLIC_ENABLE_NEXT_AUTH === '1';
7
- export const enableAuth = enableClerk || enableBetterAuth || enableNextAuth || false;
8
-
9
- export const LOBE_CHAT_AUTH_HEADER = 'X-lobe-chat-auth';
10
- export const LOBE_CHAT_OIDC_AUTH_HEADER = 'Oidc-Auth';
11
-
12
- export const OAUTH_AUTHORIZED = 'X-oauth-authorized';
13
-
14
- export const SECRET_XOR_KEY = 'LobeHub · LobeHub';