diff --git a/pkg/plugin/handler.py b/pkg/plugin/handler.py
index bc151321..5a8f9d9a 100644
--- a/pkg/plugin/handler.py
+++ b/pkg/plugin/handler.py
@@ -3,6 +3,7 @@ from __future__ import annotations
import typing
from typing import Any
import base64
+import traceback
import sqlalchemy
@@ -48,33 +49,39 @@ class RuntimeConnectionHandler(handler.Handler):
install_source = data['install_source']
install_info = data['install_info']
- result = await self.ap.persistence_mgr.execute_async(
- sqlalchemy.select(persistence_plugin.PluginSetting)
- .where(persistence_plugin.PluginSetting.plugin_author == plugin_author)
- .where(persistence_plugin.PluginSetting.plugin_name == plugin_name)
- )
-
- if result.first() is not None:
- # delete plugin setting
- await self.ap.persistence_mgr.execute_async(
- sqlalchemy.delete(persistence_plugin.PluginSetting)
+ try:
+ result = await self.ap.persistence_mgr.execute_async(
+ sqlalchemy.select(persistence_plugin.PluginSetting)
.where(persistence_plugin.PluginSetting.plugin_author == plugin_author)
.where(persistence_plugin.PluginSetting.plugin_name == plugin_name)
)
- # create plugin setting
- await self.ap.persistence_mgr.execute_async(
- sqlalchemy.insert(persistence_plugin.PluginSetting).values(
- plugin_author=plugin_author,
- plugin_name=plugin_name,
- install_source=install_source,
- install_info=install_info,
- )
- )
+ if result.first() is not None:
+ # delete plugin setting
+ await self.ap.persistence_mgr.execute_async(
+ sqlalchemy.delete(persistence_plugin.PluginSetting)
+ .where(persistence_plugin.PluginSetting.plugin_author == plugin_author)
+ .where(persistence_plugin.PluginSetting.plugin_name == plugin_name)
+ )
- return handler.ActionResponse.success(
- data={},
- )
+ # create plugin setting
+ await self.ap.persistence_mgr.execute_async(
+ sqlalchemy.insert(persistence_plugin.PluginSetting).values(
+ plugin_author=plugin_author,
+ plugin_name=plugin_name,
+ install_source=install_source,
+ install_info=install_info,
+ )
+ )
+
+ return handler.ActionResponse.success(
+ data={},
+ )
+ except Exception as e:
+ traceback.print_exc()
+ return handler.ActionResponse.error(
+ message=f'Failed to initialize plugin settings: {e}',
+ )
@self.action(RuntimeToLangBotAction.GET_PLUGIN_SETTINGS)
async def get_plugin_settings(data: dict[str, Any]) -> handler.ActionResponse:
diff --git a/web/src/app/home/plugins/page.tsx b/web/src/app/home/plugins/page.tsx
index e706e6fe..8274d025 100644
--- a/web/src/app/home/plugins/page.tsx
+++ b/web/src/app/home/plugins/page.tsx
@@ -293,7 +293,12 @@ export default function PluginConfigPage() {
)}
{pluginInstallStatus === PluginInstallStatus.ASK_CONFIRM && (
-
{t('plugins.askConfirm')}
+
+ {t('plugins.askConfirm', {
+ name: installInfo.plugin_name,
+ version: installInfo.plugin_version,
+ })}
+
)}
{pluginInstallStatus === PluginInstallStatus.INSTALLING && (
diff --git a/web/src/app/home/plugins/plugin-installed/plugin-card/PluginCardComponent.tsx b/web/src/app/home/plugins/plugin-installed/plugin-card/PluginCardComponent.tsx
index bcbc02d4..0aae5f39 100644
--- a/web/src/app/home/plugins/plugin-installed/plugin-card/PluginCardComponent.tsx
+++ b/web/src/app/home/plugins/plugin-installed/plugin-card/PluginCardComponent.tsx
@@ -5,7 +5,7 @@ import { Badge } from '@/components/ui/badge';
import { Switch } from '@/components/ui/switch';
import { toast } from 'sonner';
import { useTranslation } from 'react-i18next';
-import { ExternalLink } from 'lucide-react';
+import { BugIcon, ExternalLink } from 'lucide-react';
import { getCloudServiceClientSync } from '@/app/infra/http';
export default function PluginCardComponent({
@@ -65,48 +65,53 @@ export default function PluginCardComponent({
variant="outline"
className="text-[0.7rem] border-orange-400 text-orange-400"
>
+
{t('plugins.debugging')}
)}
- {cardVO.install_source === 'github' && (
- {
- e.stopPropagation();
- window.open(cardVO.install_info.github_url, '_blank');
- }}
- >
- {t('plugins.fromGithub')}
-
-
- )}
- {cardVO.install_source === 'local' && (
-
- {t('plugins.fromLocal')}
-
- )}
- {cardVO.install_source === 'marketplace' && (
- {
- e.stopPropagation();
- window.open(
- getCloudServiceClientSync().getPluginMarketplaceURL(
- cardVO.author,
- cardVO.name,
- ),
- '_blank',
- );
- }}
- >
- {t('plugins.fromMarketplace')}
-
-
+ {!cardVO.debug && (
+ <>
+ {cardVO.install_source === 'github' && (
+ {
+ e.stopPropagation();
+ window.open(cardVO.install_info.github_url, '_blank');
+ }}
+ >
+ {t('plugins.fromGithub')}
+
+
+ )}
+ {cardVO.install_source === 'local' && (
+
+ {t('plugins.fromLocal')}
+
+ )}
+ {cardVO.install_source === 'marketplace' && (
+ {
+ e.stopPropagation();
+ window.open(
+ getCloudServiceClientSync().getPluginMarketplaceURL(
+ cardVO.author,
+ cardVO.name,
+ ),
+ '_blank',
+ );
+ }}
+ >
+ {t('plugins.fromMarketplace')}
+
+
+ )}
+ >
)}
diff --git a/web/src/app/home/plugins/plugins.module.css b/web/src/app/home/plugins/plugins.module.css
index 54ede1c6..a65be354 100644
--- a/web/src/app/home/plugins/plugins.module.css
+++ b/web/src/app/home/plugins/plugins.module.css
@@ -13,7 +13,7 @@
padding-right: 0.8rem;
padding-top: 2rem;
display: grid;
- grid-template-columns: repeat(auto-fill, minmax(24rem, 1fr));
+ grid-template-columns: repeat(auto-fill, minmax(30rem, 1fr));
gap: 2rem;
justify-items: stretch;
align-items: start;
diff --git a/web/src/app/infra/http/CloudServiceClient.ts b/web/src/app/infra/http/CloudServiceClient.ts
index 6d67316e..f7491d5a 100644
--- a/web/src/app/infra/http/CloudServiceClient.ts
+++ b/web/src/app/infra/http/CloudServiceClient.ts
@@ -21,7 +21,10 @@ export class CloudServiceClient extends BaseHttpClient {
sort_order?: string,
): Promise {
return this.get('/api/v1/marketplace/plugins', {
- params: { page, page_size, sort_by, sort_order },
+ page,
+ page_size,
+ sort_by,
+ sort_order,
});
}
diff --git a/web/src/i18n/locales/en-US.ts b/web/src/i18n/locales/en-US.ts
index ec91858c..071930a0 100644
--- a/web/src/i18n/locales/en-US.ts
+++ b/web/src/i18n/locales/en-US.ts
@@ -189,6 +189,7 @@ const enUS = {
uploadSuccess: 'Upload successful',
uploadFailed: 'Upload failed',
selectFileToUpload: 'Select plugin file to upload',
+ askConfirm: 'Are you sure to install plugin "{{name}}" ({{version}})?',
fromGithub: 'From GitHub',
fromLocal: 'From Local',
fromMarketplace: 'From Marketplace',
diff --git a/web/src/i18n/locales/ja-JP.ts b/web/src/i18n/locales/ja-JP.ts
index 2294a254..93d48dc1 100644
--- a/web/src/i18n/locales/ja-JP.ts
+++ b/web/src/i18n/locales/ja-JP.ts
@@ -189,6 +189,7 @@ const jaJP = {
uploadSuccess: 'アップロード成功',
uploadFailed: 'アップロード失敗',
selectFileToUpload: 'アップロードするプラグインファイルを選択',
+ askConfirm: 'プラグイン "{{name}}" ({{version}}) をインストールしますか?',
fromGithub: 'GitHubから',
fromLocal: 'ローカルから',
fromMarketplace: 'プラグインマーケットから',
diff --git a/web/src/i18n/locales/zh-Hans.ts b/web/src/i18n/locales/zh-Hans.ts
index 67e1a9c8..688458e8 100644
--- a/web/src/i18n/locales/zh-Hans.ts
+++ b/web/src/i18n/locales/zh-Hans.ts
@@ -184,6 +184,7 @@ const zhHans = {
uploadSuccess: '上传成功',
uploadFailed: '上传失败',
selectFileToUpload: '选择要上传的插件文件',
+ askConfirm: '确定要安装插件 "{{name}}" ({{version}}) 吗?',
fromGithub: '来自 GitHub',
fromLocal: '来自本地',
fromMarketplace: '来自市场',