@lobehub/lobehub 2.0.0-next.141 → 2.0.0-next.143

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 (75) hide show
  1. package/CHANGELOG.md +50 -0
  2. package/Dockerfile +2 -0
  3. package/apps/desktop/package.json +1 -0
  4. package/apps/desktop/src/main/controllers/__tests__/McpInstallCtr.test.ts +286 -0
  5. package/apps/desktop/src/main/controllers/__tests__/NotificationCtr.test.ts +347 -0
  6. package/apps/desktop/src/main/controllers/__tests__/RemoteServerConfigCtr.test.ts +645 -0
  7. package/apps/desktop/src/main/controllers/__tests__/RemoteServerSyncCtr.test.ts +372 -0
  8. package/apps/desktop/src/main/controllers/__tests__/SystemCtr.test.ts +276 -0
  9. package/apps/desktop/src/main/controllers/__tests__/UploadFileCtr.test.ts +171 -0
  10. package/apps/desktop/src/main/core/browser/__tests__/Browser.test.ts +573 -0
  11. package/apps/desktop/src/main/core/browser/__tests__/BrowserManager.test.ts +415 -0
  12. package/apps/desktop/src/main/core/infrastructure/__tests__/I18nManager.test.ts +353 -0
  13. package/apps/desktop/src/main/core/infrastructure/__tests__/IoCContainer.test.ts +156 -0
  14. package/apps/desktop/src/main/core/infrastructure/__tests__/ProtocolManager.test.ts +348 -0
  15. package/apps/desktop/src/main/core/infrastructure/__tests__/StaticFileServerManager.test.ts +481 -0
  16. package/apps/desktop/src/main/core/infrastructure/__tests__/StoreManager.test.ts +164 -0
  17. package/apps/desktop/src/main/core/infrastructure/__tests__/UpdaterManager.test.ts +513 -0
  18. package/apps/desktop/src/main/core/ui/__tests__/MenuManager.test.ts +320 -0
  19. package/apps/desktop/src/main/core/ui/__tests__/Tray.test.ts +518 -0
  20. package/apps/desktop/src/main/core/ui/__tests__/TrayManager.test.ts +360 -0
  21. package/apps/desktop/src/main/menus/impls/BaseMenuPlatform.test.ts +49 -0
  22. package/apps/desktop/src/main/menus/impls/linux.test.ts +552 -0
  23. package/apps/desktop/src/main/menus/impls/macOS.test.ts +464 -0
  24. package/apps/desktop/src/main/menus/impls/windows.test.ts +429 -0
  25. package/apps/desktop/src/main/modules/fileSearch/__tests__/macOS.integration.test.ts +2 -2
  26. package/apps/desktop/src/main/services/__tests__/fileSearchSrv.test.ts +402 -0
  27. package/apps/desktop/src/main/utils/__tests__/file-system.test.ts +91 -0
  28. package/apps/desktop/src/main/utils/__tests__/logger.test.ts +229 -0
  29. package/apps/desktop/src/preload/electronApi.test.ts +142 -0
  30. package/apps/desktop/src/preload/invoke.test.ts +145 -0
  31. package/apps/desktop/src/preload/routeInterceptor.test.ts +374 -0
  32. package/apps/desktop/src/preload/streamer.test.ts +365 -0
  33. package/apps/desktop/vitest.config.mts +1 -0
  34. package/changelog/v1.json +18 -0
  35. package/docs/self-hosting/environment-variables/model-provider.mdx +31 -0
  36. package/docs/self-hosting/environment-variables/model-provider.zh-CN.mdx +30 -0
  37. package/locales/ar/marketAuth.json +13 -0
  38. package/locales/bg-BG/marketAuth.json +13 -0
  39. package/locales/de-DE/marketAuth.json +13 -0
  40. package/locales/en-US/marketAuth.json +13 -0
  41. package/locales/es-ES/marketAuth.json +13 -0
  42. package/locales/fa-IR/marketAuth.json +13 -0
  43. package/locales/fr-FR/marketAuth.json +13 -0
  44. package/locales/it-IT/marketAuth.json +13 -0
  45. package/locales/ja-JP/marketAuth.json +13 -0
  46. package/locales/ko-KR/marketAuth.json +13 -0
  47. package/locales/nl-NL/marketAuth.json +13 -0
  48. package/locales/pl-PL/marketAuth.json +13 -0
  49. package/locales/pt-BR/marketAuth.json +13 -0
  50. package/locales/ru-RU/marketAuth.json +13 -0
  51. package/locales/tr-TR/marketAuth.json +13 -0
  52. package/locales/vi-VN/marketAuth.json +13 -0
  53. package/locales/zh-CN/marketAuth.json +13 -0
  54. package/locales/zh-TW/marketAuth.json +13 -0
  55. package/package.json +1 -1
  56. package/packages/database/src/models/user.ts +2 -0
  57. package/packages/model-runtime/src/core/openaiCompatibleFactory/index.ts +6 -3
  58. package/packages/types/src/discover/mcp.ts +2 -1
  59. package/packages/types/src/tool/plugin.ts +2 -1
  60. package/src/app/[variants]/(main)/chat/settings/features/SmartAgentActionButton/MarketPublishButton.tsx +0 -2
  61. package/src/app/[variants]/(main)/discover/(detail)/mcp/features/Sidebar/ActionButton/index.tsx +33 -7
  62. package/src/config/modelProviders/vertexai.ts +1 -1
  63. package/src/envs/llm.ts +4 -0
  64. package/src/features/PluginStore/McpList/List/Action.tsx +20 -1
  65. package/src/layout/AuthProvider/MarketAuth/MarketAuthConfirmModal.tsx +158 -0
  66. package/src/layout/AuthProvider/MarketAuth/MarketAuthProvider.tsx +130 -14
  67. package/src/libs/mcp/types.ts +8 -0
  68. package/src/locales/default/marketAuth.ts +13 -0
  69. package/src/server/modules/ModelRuntime/index.ts +4 -4
  70. package/src/server/routers/lambda/market/index.ts +85 -2
  71. package/src/server/services/discover/index.ts +45 -4
  72. package/src/services/discover.ts +1 -1
  73. package/src/services/mcp.ts +18 -3
  74. package/src/store/tool/slices/mcpStore/action.test.ts +141 -0
  75. package/src/store/tool/slices/mcpStore/action.ts +153 -11
@@ -1,4 +1,15 @@
1
1
  {
2
+ "authorize": {
3
+ "cancel": "キャンセル",
4
+ "confirm": "使用を許可する",
5
+ "description": {
6
+ "and": "および",
7
+ "prefix": "「使用を許可する」をクリックすると、以下に同意したものとみなされます:",
8
+ "privacy": "プライバシーポリシー",
9
+ "terms": "利用規約"
10
+ },
11
+ "title": "認証の確認"
12
+ },
2
13
  "callback": {
3
14
  "buttons": {
4
15
  "close": "ウィンドウを閉じる"
@@ -33,8 +44,10 @@
33
44
  "stateMissing": "認証状態が見つかりません。もう一度お試しください。"
34
45
  },
35
46
  "messages": {
47
+ "authorized": "LobeHub サービスの認証に成功しました",
36
48
  "loading": "認証プロセスを開始しています...",
37
49
  "success": {
50
+ "cloudMcpInstall": "許可が成功しました!これで Cloud MCP プラグインをインストールできます。",
38
51
  "submit": "認証に成功しました!アシスタントを公開できます。",
39
52
  "upload": "認証に成功しました!新しいバージョンを公開できます。"
40
53
  }
@@ -1,4 +1,15 @@
1
1
  {
2
+ "authorize": {
3
+ "cancel": "취소",
4
+ "confirm": "사용 권한 부여",
5
+ "description": {
6
+ "and": "및",
7
+ "prefix": "사용 권한 부여를 클릭하면 다음에 동의한 것으로 간주됩니다",
8
+ "privacy": "개인정보 처리방침",
9
+ "terms": "서비스 이용약관"
10
+ },
11
+ "title": "권한 확인"
12
+ },
2
13
  "callback": {
3
14
  "buttons": {
4
15
  "close": "창 닫기"
@@ -33,8 +44,10 @@
33
44
  "stateMissing": "인증 상태를 찾을 수 없습니다. 다시 시도해 주세요."
34
45
  },
35
46
  "messages": {
47
+ "authorized": "LobeHub 서비스가 성공적으로 인증되었습니다",
36
48
  "loading": "인증 절차를 시작하는 중입니다...",
37
49
  "success": {
50
+ "cloudMcpInstall": "권한 부여 완료! 이제 Cloud MCP 플러그인을 설치할 수 있습니다.",
38
51
  "submit": "인증 성공! 이제 어시스턴트를 게시할 수 있습니다.",
39
52
  "upload": "인증 성공! 이제 새 버전을 게시할 수 있습니다."
40
53
  }
@@ -1,4 +1,15 @@
1
1
  {
2
+ "authorize": {
3
+ "cancel": "Annuleren",
4
+ "confirm": "Toestemming geven",
5
+ "description": {
6
+ "and": "en",
7
+ "prefix": "Door op 'Toestemming geven' te klikken, ga je akkoord met onze",
8
+ "privacy": "Privacybeleid",
9
+ "terms": "Servicevoorwaarden"
10
+ },
11
+ "title": "Autorisatie bevestigen"
12
+ },
2
13
  "callback": {
3
14
  "buttons": {
4
15
  "close": "Venster sluiten"
@@ -33,8 +44,10 @@
33
44
  "stateMissing": "Autorisatiestatus niet gevonden, probeer het opnieuw."
34
45
  },
35
46
  "messages": {
47
+ "authorized": "LobeHub-service succesvol geautoriseerd",
36
48
  "loading": "Autorisatieproces wordt gestart...",
37
49
  "success": {
50
+ "cloudMcpInstall": "Toestemming succesvol! Je kunt nu de Cloud MCP-plugin installeren.",
38
51
  "submit": "Autorisatie geslaagd! Je kunt nu een assistent publiceren.",
39
52
  "upload": "Autorisatie geslaagd! Je kunt nu een nieuwe versie publiceren."
40
53
  }
@@ -1,4 +1,15 @@
1
1
  {
2
+ "authorize": {
3
+ "cancel": "Anuluj",
4
+ "confirm": "Autoryzuj użycie",
5
+ "description": {
6
+ "and": "oraz",
7
+ "prefix": "Klikając „Autoryzuj użycie”, wyrażasz zgodę na",
8
+ "privacy": "Politykę prywatności",
9
+ "terms": "Warunki korzystania z usługi"
10
+ },
11
+ "title": "Potwierdź autoryzację"
12
+ },
2
13
  "callback": {
3
14
  "buttons": {
4
15
  "close": "Zamknij okno"
@@ -33,8 +44,10 @@
33
44
  "stateMissing": "Nie znaleziono stanu autoryzacji, spróbuj ponownie."
34
45
  },
35
46
  "messages": {
47
+ "authorized": "Autoryzacja usługi LobeHub zakończona pomyślnie",
36
48
  "loading": "Uruchamianie procesu autoryzacji...",
37
49
  "success": {
50
+ "cloudMcpInstall": "Autoryzacja zakończona sukcesem! Możesz teraz zainstalować wtyczkę Cloud MCP.",
38
51
  "submit": "Autoryzacja zakończona sukcesem! Możesz teraz opublikować asystenta.",
39
52
  "upload": "Autoryzacja zakończona sukcesem! Możesz teraz opublikować nową wersję."
40
53
  }
@@ -1,4 +1,15 @@
1
1
  {
2
+ "authorize": {
3
+ "cancel": "Cancelar",
4
+ "confirm": "Autorizar uso",
5
+ "description": {
6
+ "and": "e",
7
+ "prefix": "Ao clicar em autorizar uso, você concorda com",
8
+ "privacy": "Política de Privacidade",
9
+ "terms": "Termos de Serviço"
10
+ },
11
+ "title": "Confirmar Autorização"
12
+ },
2
13
  "callback": {
3
14
  "buttons": {
4
15
  "close": "Fechar janela"
@@ -33,8 +44,10 @@
33
44
  "stateMissing": "Estado de autorização não encontrado, tente novamente."
34
45
  },
35
46
  "messages": {
47
+ "authorized": "Autorização do serviço LobeHub realizada com sucesso",
36
48
  "loading": "Iniciando o processo de autorização...",
37
49
  "success": {
50
+ "cloudMcpInstall": "Autorização bem-sucedida! Agora você pode instalar o plugin Cloud MCP.",
38
51
  "submit": "Autorização bem-sucedida! Agora você pode publicar o assistente.",
39
52
  "upload": "Autorização bem-sucedida! Agora você pode publicar uma nova versão."
40
53
  }
@@ -1,4 +1,15 @@
1
1
  {
2
+ "authorize": {
3
+ "cancel": "Отмена",
4
+ "confirm": "Подтвердить доступ",
5
+ "description": {
6
+ "and": "и",
7
+ "prefix": "Нажимая «Подтвердить доступ», вы соглашаетесь с",
8
+ "privacy": "Политикой конфиденциальности",
9
+ "terms": "Условиями обслуживания"
10
+ },
11
+ "title": "Подтвердить авторизацию"
12
+ },
2
13
  "callback": {
3
14
  "buttons": {
4
15
  "close": "Закрыть окно"
@@ -33,8 +44,10 @@
33
44
  "stateMissing": "Состояние авторизации не найдено, пожалуйста, попробуйте снова."
34
45
  },
35
46
  "messages": {
47
+ "authorized": "Авторизация сервиса LobeHub прошла успешно",
36
48
  "loading": "Запуск процесса авторизации...",
37
49
  "success": {
50
+ "cloudMcpInstall": "Доступ успешно предоставлен! Теперь вы можете установить плагин Cloud MCP.",
38
51
  "submit": "Авторизация прошла успешно! Теперь вы можете опубликовать помощника.",
39
52
  "upload": "Авторизация прошла успешно! Теперь вы можете опубликовать новую версию."
40
53
  }
@@ -1,4 +1,15 @@
1
1
  {
2
+ "authorize": {
3
+ "cancel": "İptal",
4
+ "confirm": "Kullanıma Yetki Ver",
5
+ "description": {
6
+ "and": "ve",
7
+ "prefix": "Kullanıma yetki ver'e tıklayarak şu şartları kabul etmiş olursunuz:",
8
+ "privacy": "Gizlilik Politikası",
9
+ "terms": "Hizmet Şartları"
10
+ },
11
+ "title": "Yetkilendirmeyi Onayla"
12
+ },
2
13
  "callback": {
3
14
  "buttons": {
4
15
  "close": "Pencereyi Kapat"
@@ -33,8 +44,10 @@
33
44
  "stateMissing": "Yetkilendirme durumu bulunamadı, lütfen tekrar deneyin."
34
45
  },
35
46
  "messages": {
47
+ "authorized": "LobeHub hizmet yetkilendirmesi başarıyla tamamlandı",
36
48
  "loading": "Yetkilendirme süreci başlatılıyor...",
37
49
  "success": {
50
+ "cloudMcpInstall": "Yetkilendirme başarılı! Artık Cloud MCP eklentisini yükleyebilirsiniz.",
38
51
  "submit": "Yetkilendirme başarılı! Artık asistan yayınlayabilirsiniz.",
39
52
  "upload": "Yetkilendirme başarılı! Artık yeni bir sürüm yayınlayabilirsiniz."
40
53
  }
@@ -1,4 +1,15 @@
1
1
  {
2
+ "authorize": {
3
+ "cancel": "Hủy",
4
+ "confirm": "Ủy quyền sử dụng",
5
+ "description": {
6
+ "and": "và",
7
+ "prefix": "Bằng cách nhấp vào ủy quyền sử dụng, bạn đồng ý với",
8
+ "privacy": "Chính sách quyền riêng tư",
9
+ "terms": "Điều khoản dịch vụ"
10
+ },
11
+ "title": "Xác nhận ủy quyền"
12
+ },
2
13
  "callback": {
3
14
  "buttons": {
4
15
  "close": "Đóng cửa sổ"
@@ -33,8 +44,10 @@
33
44
  "stateMissing": "Không tìm thấy trạng thái xác thực, vui lòng thử lại."
34
45
  },
35
46
  "messages": {
47
+ "authorized": "Dịch vụ LobeHub đã được cấp quyền thành công",
36
48
  "loading": "Đang khởi động quy trình xác thực...",
37
49
  "success": {
50
+ "cloudMcpInstall": "Ủy quyền thành công! Bây giờ bạn có thể cài đặt plugin Cloud MCP.",
38
51
  "submit": "Xác thực thành công! Bây giờ bạn có thể xuất bản trợ lý.",
39
52
  "upload": "Xác thực thành công! Bây giờ bạn có thể xuất bản phiên bản mới."
40
53
  }
@@ -1,4 +1,15 @@
1
1
  {
2
+ "authorize": {
3
+ "cancel": "取消",
4
+ "confirm": "授权使用",
5
+ "description": {
6
+ "and": "和",
7
+ "prefix": "点击授权使用即视为同意",
8
+ "privacy": "隐私协议",
9
+ "terms": "服务条款"
10
+ },
11
+ "title": "确认授权"
12
+ },
2
13
  "callback": {
3
14
  "buttons": {
4
15
  "close": "关闭窗口"
@@ -33,8 +44,10 @@
33
44
  "stateMissing": "未找到授权状态,请重试。"
34
45
  },
35
46
  "messages": {
47
+ "authorized": "LobeHub 服务授权成功",
36
48
  "loading": "正在启动授权流程...",
37
49
  "success": {
50
+ "cloudMcpInstall": "授权成功!现在可以安装 Cloud MCP 插件了。",
38
51
  "submit": "授权成功!现在可以发布助手了。",
39
52
  "upload": "授权成功!现在可以发布新版本了。"
40
53
  }
@@ -1,4 +1,15 @@
1
1
  {
2
+ "authorize": {
3
+ "cancel": "取消",
4
+ "confirm": "授權使用",
5
+ "description": {
6
+ "and": "和",
7
+ "prefix": "點擊授權使用即視為同意",
8
+ "privacy": "隱私協議",
9
+ "terms": "服務條款"
10
+ },
11
+ "title": "確認授權"
12
+ },
2
13
  "callback": {
3
14
  "buttons": {
4
15
  "close": "關閉視窗"
@@ -33,8 +44,10 @@
33
44
  "stateMissing": "找不到授權狀態,請重試。"
34
45
  },
35
46
  "messages": {
47
+ "authorized": "LobeHub 服務授權成功",
36
48
  "loading": "正在啟動授權流程⋯⋯",
37
49
  "success": {
50
+ "cloudMcpInstall": "授權成功!現在可以安裝 Cloud MCP 外掛了。",
38
51
  "submit": "授權成功!現在可以發佈助手了。",
39
52
  "upload": "授權成功!現在可以發佈新版本了。"
40
53
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lobehub/lobehub",
3
- "version": "2.0.0-next.141",
3
+ "version": "2.0.0-next.143",
4
4
  "description": "LobeHub - an open-source,comprehensive AI Agent framework that supports speech synthesis, multimodal, and extensible Function Call plugin system. Supports one-click free deployment of your private ChatGPT/LLM web application.",
5
5
  "keywords": [
6
6
  "framework",
@@ -80,6 +80,7 @@ export class UserModel {
80
80
  settingsImage: userSettings.image,
81
81
  settingsKeyVaults: userSettings.keyVaults,
82
82
  settingsLanguageModel: userSettings.languageModel,
83
+ settingsMarket: userSettings.market,
83
84
  settingsSystemAgent: userSettings.systemAgent,
84
85
  settingsTTS: userSettings.tts,
85
86
  settingsTool: userSettings.tool,
@@ -112,6 +113,7 @@ export class UserModel {
112
113
  image: state.settingsImage || {},
113
114
  keyVaults: decryptKeyVaults,
114
115
  languageModel: state.settingsLanguageModel || {},
116
+ market: state.settingsMarket || undefined,
115
117
  systemAgent: state.settingsSystemAgent || {},
116
118
  tool: state.settingsTool || {},
117
119
  tts: state.settingsTTS || {},
@@ -368,8 +368,11 @@ export const createOpenAICompatibleRuntime = <T extends Record<string, any> = an
368
368
  this,
369
369
  ) as any;
370
370
  } else {
371
+ // Remove internal apiMode parameter before sending to API
372
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
373
+ const { apiMode: _, ...cleanedPayload } = postPayload as any;
371
374
  const finalPayload = {
372
- ...postPayload,
375
+ ...cleanedPayload,
373
376
  messages,
374
377
  ...(chatCompletion?.noUserId ? {} : { user: options?.user }),
375
378
  stream_options:
@@ -385,11 +388,11 @@ export const createOpenAICompatibleRuntime = <T extends Record<string, any> = an
385
388
  console.log(JSON.stringify(finalPayload), '\n');
386
389
  }
387
390
 
388
- response = await this.client.chat.completions.create(finalPayload, {
391
+ response = (await this.client.chat.completions.create(finalPayload, {
389
392
  // https://github.com/lobehub/lobe-chat/pull/318
390
393
  headers: { Accept: '*/*', ...options?.requestHeaders },
391
394
  signal: options?.signal,
392
- });
395
+ })) as unknown as Stream<OpenAI.Chat.Completions.ChatCompletionChunk>;
393
396
  }
394
397
 
395
398
  if (postPayload.stream) {
@@ -41,7 +41,7 @@ export enum McpNavKey {
41
41
 
42
42
  export enum McpConnectionType {
43
43
  http = 'http',
44
- stdio = 'stdio'
44
+ stdio = 'stdio',
45
45
  }
46
46
 
47
47
  export type DiscoverMcpItem = PluginItem;
@@ -60,6 +60,7 @@ export interface McpQueryParams {
60
60
  export type McpListResponse = PluginListResponse;
61
61
 
62
62
  export interface DiscoverMcpDetail extends PluginItemDetail {
63
+ haveCloudEndpoint?: boolean;
63
64
  isClaimed?: boolean;
64
65
  related: DiscoverMcpItem[];
65
66
  }
@@ -25,8 +25,9 @@ export interface CustomPluginParams {
25
25
  args?: string[];
26
26
  env?: Record<string, string>;
27
27
  command?: string;
28
- type: 'http' | 'stdio';
28
+ type: 'http' | 'stdio' | 'cloud';
29
29
  url?: string;
30
+ cloudEndPoint?: string; // Cloud gateway endpoint for cloud type
30
31
  // Added authentication configuration support
31
32
  auth?: {
32
33
  type: 'none' | 'bearer' | 'oauth2';
@@ -87,9 +87,7 @@ const MarketPublishButton = memo<MarketPublishButtonProps>(
87
87
  `[MarketPublishButton][${action}] User not authenticated, starting authorization`,
88
88
  );
89
89
  try {
90
- message.loading({ content: tMarketAuth('messages.loading'), key: 'market-auth' });
91
90
  const accountId = await signIn();
92
- message.success({ content: buttonCopy.successMessage, key: 'market-auth' });
93
91
 
94
92
  let targetAction: MarketPublishAction = action;
95
93
 
@@ -10,6 +10,7 @@ import { Flexbox } from 'react-layout-kit';
10
10
 
11
11
  import MCPInstallProgress from '@/features/MCP/MCPInstallProgress';
12
12
  import { useDetailContext } from '@/features/MCPPluginDetail/DetailProvider';
13
+ import { useMarketAuth } from '@/layout/AuthProvider/MarketAuth';
13
14
  import { useToolStore } from '@/store/tool';
14
15
  import { pluginSelectors } from '@/store/tool/slices/plugin/selectors';
15
16
 
@@ -23,9 +24,11 @@ const useStyles = createStyles(({ css }) => ({
23
24
 
24
25
  const ActionButton = memo(() => {
25
26
  const { t } = useTranslation(['discover', 'plugin']);
26
- const { identifier } = useDetailContext();
27
+ const detailContext = useDetailContext();
28
+ const { identifier, haveCloudEndpoint } = detailContext;
27
29
  const { styles } = useStyles();
28
30
  const [isLoading, setIsLoading] = useState(false);
31
+ const { isAuthenticated, isLoading: isAuthLoading, signIn } = useMarketAuth();
29
32
 
30
33
  const [installed, installMCPPlugin, uninstallMCPPlugin] = useToolStore((s) => [
31
34
  pluginSelectors.isPluginInstalled(identifier!)(s),
@@ -33,24 +36,47 @@ const ActionButton = memo(() => {
33
36
  s.uninstallMCPPlugin,
34
37
  ]);
35
38
 
39
+ // Check if this is a cloud MCP plugin
40
+ const isCloudMcp = haveCloudEndpoint;
41
+
36
42
  const installPlugin = async () => {
37
43
  if (!identifier) return;
38
- setIsLoading(true);
39
44
 
40
- await installMCPPlugin(identifier);
45
+ // If this is a cloud MCP and user is not authenticated, request authorization first
46
+ if (isCloudMcp && !isAuthenticated) {
47
+ try {
48
+ await signIn();
49
+ } catch {
50
+ return; // Don't proceed with installation if auth fails
51
+ }
52
+ }
41
53
 
42
- setIsLoading(false);
54
+ // Proceed with installation
55
+ setIsLoading(true);
56
+ try {
57
+ await installMCPPlugin(identifier);
58
+ } finally {
59
+ setIsLoading(false);
60
+ }
43
61
  };
44
62
 
63
+ const buttonLoading = isLoading || isAuthLoading;
64
+
45
65
  return installed ? (
46
66
  <Flexbox gap={8} horizontal>
47
- <Button block className={styles.button} disabled={isLoading} size={'large'} type={'default'}>
67
+ <Button
68
+ block
69
+ className={styles.button}
70
+ disabled={buttonLoading}
71
+ size={'large'}
72
+ type={'default'}
73
+ >
48
74
  {t('plugins.installed')}
49
75
  </Button>
50
76
 
51
77
  <Button
52
78
  icon={<Icon icon={Trash2Icon} size={20} />}
53
- loading={isLoading}
79
+ loading={buttonLoading}
54
80
  onClick={async () => {
55
81
  setIsLoading(true);
56
82
  await uninstallMCPPlugin(identifier!);
@@ -68,7 +94,7 @@ const ActionButton = memo(() => {
68
94
  <Button
69
95
  block
70
96
  className={styles.button}
71
- loading={isLoading}
97
+ loading={buttonLoading}
72
98
  onClick={installPlugin}
73
99
  size={'large'}
74
100
  type={'primary'}
@@ -3,7 +3,7 @@ import { ModelProviderCard } from '@/types/llm';
3
3
  // ref: https://ai.google.dev/gemini-api/docs/models/gemini
4
4
  const VertexAI: ModelProviderCard = {
5
5
  chatModels: [],
6
- checkModel: 'gemini-1.5-flash-001',
6
+ checkModel: 'gemini-2.0-flash',
7
7
  description:
8
8
  'Google 的 Gemini 系列是其最先进、通用的 AI模型,由 Google DeepMind 打造,专为多模态设计,支持文本、代码、图像、音频和视频的无缝理解与处理。适用于从数据中心到移动设备的多种环境,极大提升了AI模型的效率与应用广泛性。',
9
9
  id: 'vertexai',
package/src/envs/llm.ts CHANGED
@@ -28,6 +28,8 @@ export const getLLMConfig = () => {
28
28
  ENABLED_GOOGLE: z.boolean(),
29
29
  GOOGLE_API_KEY: z.string().optional(),
30
30
 
31
+ ENABLED_VERTEXAI: z.boolean(),
32
+
31
33
  ENABLED_MOONSHOT: z.boolean(),
32
34
  MOONSHOT_API_KEY: z.string().optional(),
33
35
 
@@ -237,6 +239,8 @@ export const getLLMConfig = () => {
237
239
  ENABLED_GOOGLE: !!process.env.GOOGLE_API_KEY,
238
240
  GOOGLE_API_KEY: process.env.GOOGLE_API_KEY,
239
241
 
242
+ ENABLED_VERTEXAI: !!process.env.VERTEXAI_CREDENTIALS,
243
+
240
244
  ENABLED_VOLCENGINE: !!process.env.VOLCENGINE_API_KEY,
241
245
  VOLCENGINE_API_KEY: process.env.VOLCENGINE_API_KEY,
242
246
 
@@ -5,6 +5,7 @@ import { memo } from 'react';
5
5
  import { useTranslation } from 'react-i18next';
6
6
  import { Flexbox } from 'react-layout-kit';
7
7
 
8
+ import { useMarketAuth } from '@/layout/AuthProvider/MarketAuth';
8
9
  import { useAgentStore } from '@/store/agent';
9
10
  import { agentSelectors } from '@/store/agent/selectors';
10
11
  import { useToolStore } from '@/store/tool';
@@ -15,13 +16,14 @@ interface ActionsProps {
15
16
  }
16
17
 
17
18
  const Actions = memo<ActionsProps>(({ identifier }) => {
18
- const [installed, installing, unInstallPlugin, installMCPPlugin, cancelInstallMCPPlugin] =
19
+ const [installed, installing, unInstallPlugin, installMCPPlugin, cancelInstallMCPPlugin, plugin] =
19
20
  useToolStore((s) => [
20
21
  pluginSelectors.isPluginInstalled(identifier)(s),
21
22
  mcpStoreSelectors.isMCPInstalling(identifier)(s),
22
23
  s.uninstallPlugin,
23
24
  s.installMCPPlugin,
24
25
  s.cancelInstallMCPPlugin,
26
+ mcpStoreSelectors.getPluginById(identifier)(s),
25
27
  ]);
26
28
 
27
29
  const { t } = useTranslation('plugin');
@@ -30,6 +32,10 @@ const Actions = memo<ActionsProps>(({ identifier }) => {
30
32
  agentSelectors.currentAgentPlugins(s).includes(identifier),
31
33
  ]);
32
34
  const { modal } = App.useApp();
35
+ const { isAuthenticated, signIn } = useMarketAuth();
36
+
37
+ // Check if this is a cloud MCP plugin
38
+ const isCloudMcp = !!((plugin as any)?.cloudEndPoint || (plugin as any)?.haveCloudEndpoint);
33
39
 
34
40
  return (
35
41
  <Flexbox align={'center'} horizontal>
@@ -86,6 +92,19 @@ const Actions = memo<ActionsProps>(({ identifier }) => {
86
92
  onClick={async (e) => {
87
93
  e.stopPropagation();
88
94
 
95
+ // If this is a cloud MCP and user is not authenticated, request authorization first
96
+ if (isCloudMcp && !isAuthenticated) {
97
+ console.log(
98
+ '[MCPListAction] Cloud MCP detected, user not authenticated, starting authorization',
99
+ );
100
+
101
+ try {
102
+ await signIn();
103
+ } catch {
104
+ return; // Don't proceed with installation if auth fails
105
+ }
106
+ }
107
+
89
108
  const isSuccess = await installMCPPlugin(identifier);
90
109
 
91
110
  if (isSuccess) {