mirror of
https://github.com/langbot-app/LangBot.git
synced 2026-06-03 12:34:37 +00:00
Feat/pipeline enable all extensions (#1807)
* feat: 添加流水线扩展集成"启用所有"选项
为流水线的扩展集成配置添加独立的"启用所有插件"和"启用所有MCP服务器"选项。
主要变更:
- 数据模型:在 extensions_preferences 中添加 enable_all_plugins 和 enable_all_mcp_servers 字段
- 后端逻辑:修改 RuntimePipeline 以支持独立的启用所有选项,当启用时设置为 None 表示使用所有可用资源
- API 接口:更新 GET/PUT /api/v1/pipelines/{uuid}/extensions 以支持新字段
- 前端 UI:为插件和 MCP 服务器分别添加独立的开关控件
- 国际化:添加对应的中文翻译文本
- 默认行为:新创建的流水线默认启用所有插件和 MCP 服务器
🤖 Generated with [Claude Code](https://claude.com/claude-code)
via [Happy](https://happy.engineering)
Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
* fix(i18n): add missing translations for pipeline extensions
Added translations for enable all plugins/MCP servers feature:
- en-US: English translations
- ja-JP: Japanese translations
- zh-Hant: Traditional Chinese translations
Generated with [Claude Code](https://claude.ai/code)
via [Happy](https://happy.engineering)
Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
* chore: add migration for enable all extensions config
* fix: bad renaming
---------
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Happy <yesreply@happy.engineering>
This commit is contained in:
committed by
GitHub
parent
7d51293594
commit
87131cf03b
@@ -16,6 +16,8 @@ import {
|
||||
import { Checkbox } from '@/components/ui/checkbox';
|
||||
import { Plus, X, Server, Wrench } from 'lucide-react';
|
||||
import { Badge } from '@/components/ui/badge';
|
||||
import { Switch } from '@/components/ui/switch';
|
||||
import { Label } from '@/components/ui/label';
|
||||
import { Plugin } from '@/app/infra/entities/plugin';
|
||||
import { MCPServer } from '@/app/infra/entities/api';
|
||||
import PluginComponentList from '@/app/home/plugins/components/plugin-installed/PluginComponentList';
|
||||
@@ -27,6 +29,8 @@ export default function PipelineExtension({
|
||||
}) {
|
||||
const { t } = useTranslation();
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [enableAllPlugins, setEnableAllPlugins] = useState(true);
|
||||
const [enableAllMCPServers, setEnableAllMCPServers] = useState(true);
|
||||
const [selectedPlugins, setSelectedPlugins] = useState<Plugin[]>([]);
|
||||
const [allPlugins, setAllPlugins] = useState<Plugin[]>([]);
|
||||
const [selectedMCPServers, setSelectedMCPServers] = useState<MCPServer[]>([]);
|
||||
@@ -53,6 +57,9 @@ export default function PipelineExtension({
|
||||
setLoading(true);
|
||||
const data = await backendClient.getPipelineExtensions(pipelineId);
|
||||
|
||||
setEnableAllPlugins(data.enable_all_plugins ?? true);
|
||||
setEnableAllMCPServers(data.enable_all_mcp_servers ?? true);
|
||||
|
||||
const boundPluginIds = new Set(
|
||||
data.bound_plugins.map((p) => `${p.author}/${p.name}`),
|
||||
);
|
||||
@@ -80,7 +87,12 @@ export default function PipelineExtension({
|
||||
}
|
||||
};
|
||||
|
||||
const saveToBackend = async (plugins: Plugin[], mcpServers: MCPServer[]) => {
|
||||
const saveToBackend = async (
|
||||
plugins: Plugin[],
|
||||
mcpServers: MCPServer[],
|
||||
newEnableAllPlugins?: boolean,
|
||||
newEnableAllMCPServers?: boolean,
|
||||
) => {
|
||||
try {
|
||||
const boundPluginsArray = plugins.map((plugin) => {
|
||||
const metadata = plugin.manifest.manifest.metadata;
|
||||
@@ -96,6 +108,8 @@ export default function PipelineExtension({
|
||||
pipelineId,
|
||||
boundPluginsArray,
|
||||
boundMCPServerIds,
|
||||
newEnableAllPlugins ?? enableAllPlugins,
|
||||
newEnableAllMCPServers ?? enableAllMCPServers,
|
||||
);
|
||||
toast.success(t('pipelines.extensions.saveSuccess'));
|
||||
} catch (error) {
|
||||
@@ -184,6 +198,26 @@ export default function PipelineExtension({
|
||||
await saveToBackend(selectedPlugins, newSelected);
|
||||
};
|
||||
|
||||
const handleToggleEnableAllPlugins = async (checked: boolean) => {
|
||||
setEnableAllPlugins(checked);
|
||||
await saveToBackend(
|
||||
selectedPlugins,
|
||||
selectedMCPServers,
|
||||
checked,
|
||||
undefined,
|
||||
);
|
||||
};
|
||||
|
||||
const handleToggleEnableAllMCPServers = async (checked: boolean) => {
|
||||
setEnableAllMCPServers(checked);
|
||||
await saveToBackend(
|
||||
selectedPlugins,
|
||||
selectedMCPServers,
|
||||
undefined,
|
||||
checked,
|
||||
);
|
||||
};
|
||||
|
||||
if (loading) {
|
||||
return (
|
||||
<div className="space-y-4">
|
||||
@@ -198,11 +232,32 @@ export default function PipelineExtension({
|
||||
<div className="space-y-6">
|
||||
{/* Plugins Section */}
|
||||
<div className="space-y-3">
|
||||
<h3 className="text-sm font-semibold text-foreground">
|
||||
{t('pipelines.extensions.pluginsTitle')}
|
||||
</h3>
|
||||
<div className="flex items-center justify-between">
|
||||
<h3 className="text-sm font-semibold text-foreground">
|
||||
{t('pipelines.extensions.pluginsTitle')}
|
||||
</h3>
|
||||
<div className="flex items-center gap-2">
|
||||
<Label
|
||||
htmlFor="enable-all-plugins"
|
||||
className="text-sm font-normal cursor-pointer"
|
||||
>
|
||||
{t('pipelines.extensions.enableAllPlugins')}
|
||||
</Label>
|
||||
<Switch
|
||||
id="enable-all-plugins"
|
||||
checked={enableAllPlugins}
|
||||
onCheckedChange={handleToggleEnableAllPlugins}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="space-y-2">
|
||||
{selectedPlugins.length === 0 ? (
|
||||
{enableAllPlugins ? (
|
||||
<div className="flex h-32 items-center justify-center rounded-lg border-2 border-dashed border-border bg-muted/30">
|
||||
<p className="text-sm text-muted-foreground">
|
||||
{t('pipelines.extensions.allPluginsEnabled')}
|
||||
</p>
|
||||
</div>
|
||||
) : selectedPlugins.length === 0 ? (
|
||||
<div className="flex h-32 items-center justify-center rounded-lg border-2 border-dashed border-border">
|
||||
<p className="text-sm text-muted-foreground">
|
||||
{t('pipelines.extensions.noPluginsSelected')}
|
||||
@@ -278,6 +333,7 @@ export default function PipelineExtension({
|
||||
onClick={handleOpenPluginDialog}
|
||||
variant="outline"
|
||||
className="w-full"
|
||||
disabled={enableAllPlugins}
|
||||
>
|
||||
<Plus className="mr-2 h-4 w-4" />
|
||||
{t('pipelines.extensions.addPlugin')}
|
||||
@@ -286,11 +342,32 @@ export default function PipelineExtension({
|
||||
|
||||
{/* MCP Servers Section */}
|
||||
<div className="space-y-3">
|
||||
<h3 className="text-sm font-semibold text-foreground">
|
||||
{t('pipelines.extensions.mcpServersTitle')}
|
||||
</h3>
|
||||
<div className="flex items-center justify-between">
|
||||
<h3 className="text-sm font-semibold text-foreground">
|
||||
{t('pipelines.extensions.mcpServersTitle')}
|
||||
</h3>
|
||||
<div className="flex items-center gap-2">
|
||||
<Label
|
||||
htmlFor="enable-all-mcp-servers"
|
||||
className="text-sm font-normal cursor-pointer"
|
||||
>
|
||||
{t('pipelines.extensions.enableAllMCPServers')}
|
||||
</Label>
|
||||
<Switch
|
||||
id="enable-all-mcp-servers"
|
||||
checked={enableAllMCPServers}
|
||||
onCheckedChange={handleToggleEnableAllMCPServers}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="space-y-2">
|
||||
{selectedMCPServers.length === 0 ? (
|
||||
{enableAllMCPServers ? (
|
||||
<div className="flex h-32 items-center justify-center rounded-lg border-2 border-dashed border-border bg-muted/30">
|
||||
<p className="text-sm text-muted-foreground">
|
||||
{t('pipelines.extensions.allMCPServersEnabled')}
|
||||
</p>
|
||||
</div>
|
||||
) : selectedMCPServers.length === 0 ? (
|
||||
<div className="flex h-32 items-center justify-center rounded-lg border-2 border-dashed border-border">
|
||||
<p className="text-sm text-muted-foreground">
|
||||
{t('pipelines.extensions.noMCPServersSelected')}
|
||||
@@ -350,6 +427,7 @@ export default function PipelineExtension({
|
||||
onClick={handleOpenMCPDialog}
|
||||
variant="outline"
|
||||
className="w-full"
|
||||
disabled={enableAllMCPServers}
|
||||
>
|
||||
<Plus className="mr-2 h-4 w-4" />
|
||||
{t('pipelines.extensions.addMCPServer')}
|
||||
|
||||
@@ -171,6 +171,8 @@ export class BackendClient extends BaseHttpClient {
|
||||
}
|
||||
|
||||
public getPipelineExtensions(uuid: string): Promise<{
|
||||
enable_all_plugins: boolean;
|
||||
enable_all_mcp_servers: boolean;
|
||||
bound_plugins: Array<{ author: string; name: string }>;
|
||||
available_plugins: Plugin[];
|
||||
bound_mcp_servers: string[];
|
||||
@@ -183,10 +185,14 @@ export class BackendClient extends BaseHttpClient {
|
||||
uuid: string,
|
||||
bound_plugins: Array<{ author: string; name: string }>,
|
||||
bound_mcp_servers: string[],
|
||||
enable_all_plugins: boolean = true,
|
||||
enable_all_mcp_servers: boolean = true,
|
||||
): Promise<object> {
|
||||
return this.put(`/api/v1/pipelines/${uuid}/extensions`, {
|
||||
bound_plugins,
|
||||
bound_mcp_servers,
|
||||
enable_all_plugins,
|
||||
enable_all_mcp_servers,
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -494,6 +494,10 @@ const enUS = {
|
||||
noPluginsInstalled: 'No installed plugins',
|
||||
noMCPServersConfigured: 'No configured MCP servers',
|
||||
selectAll: 'Select All',
|
||||
enableAllPlugins: 'Enable All Plugins',
|
||||
enableAllMCPServers: 'Enable All MCP Servers',
|
||||
allPluginsEnabled: 'All plugins enabled',
|
||||
allMCPServersEnabled: 'All MCP servers enabled',
|
||||
},
|
||||
debugDialog: {
|
||||
title: 'Pipeline Chat',
|
||||
|
||||
@@ -497,6 +497,10 @@ const jaJP = {
|
||||
noPluginsInstalled: 'インストールされているプラグインがありません',
|
||||
noMCPServersConfigured: '設定されているMCPサーバーがありません',
|
||||
selectAll: 'すべて選択',
|
||||
enableAllPlugins: 'すべてのプラグインを有効にする',
|
||||
enableAllMCPServers: 'すべてのMCPサーバーを有効にする',
|
||||
allPluginsEnabled: 'すべてのプラグインが有効になっています',
|
||||
allMCPServersEnabled: 'すべてのMCPサーバーが有効になっています',
|
||||
},
|
||||
debugDialog: {
|
||||
title: 'パイプラインのチャット',
|
||||
|
||||
@@ -476,6 +476,10 @@ const zhHans = {
|
||||
noPluginsInstalled: '无已安装的插件',
|
||||
noMCPServersConfigured: '无已配置的 MCP 服务器',
|
||||
selectAll: '全选',
|
||||
enableAllPlugins: '启用所有插件',
|
||||
enableAllMCPServers: '启用所有 MCP 服务器',
|
||||
allPluginsEnabled: '已启用所有插件',
|
||||
allMCPServersEnabled: '已启用所有 MCP 服务器',
|
||||
},
|
||||
debugDialog: {
|
||||
title: '流水线对话',
|
||||
|
||||
@@ -474,6 +474,10 @@ const zhHant = {
|
||||
noPluginsInstalled: '無已安裝的插件',
|
||||
noMCPServersConfigured: '無已配置的 MCP 伺服器',
|
||||
selectAll: '全選',
|
||||
enableAllPlugins: '啟用所有插件',
|
||||
enableAllMCPServers: '啟用所有 MCP 伺服器',
|
||||
allPluginsEnabled: '已啟用所有插件',
|
||||
allMCPServersEnabled: '已啟用所有 MCP 伺服器',
|
||||
},
|
||||
debugDialog: {
|
||||
title: '流程線對話',
|
||||
|
||||
Reference in New Issue
Block a user