feat: 添加swarms团队编排功能并优化agent委派系统

- 引入AgentTeamOrchestrator支持多agent协同任务执行
- 增加第三方swarms库依赖并配置git协议替换以改善包管理
- 扩展DelegationManager支持团队任务调度和进度跟踪
- 实现中文bigram分词算法提升中文任务检索准确性
- 调整A2AClient和DelegationManager超时时间从30秒增至600秒
- 优化AgentRunResult状态判断逻辑增加有意义摘要检测
- 修改Dockerfile配置npm仓库镜像地址和git协议映射
- 更新CLI命令行接口支持网关端口配置传递
- 调整提供者超时配置机制增强请求稳定性
- 移除过时的support_group字段简化agent描述符结构
- 增强错误处理和进度事件报告机制改进用户体验
This commit is contained in:
2026-04-14 14:34:23 +08:00
parent fee9007da6
commit cdfc222c9f
85 changed files with 5443 additions and 1392 deletions

View File

@ -19,8 +19,11 @@ import { Button } from '@/components/ui/button';
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
import { Badge } from '@/components/ui/badge';
import type { PluginInfo } from '@/types';
import { pickAppText } from '@/lib/i18n/core';
import { useAppI18n } from '@/lib/i18n/provider';
export default function PluginsPage() {
const { locale } = useAppI18n();
const [plugins, setPlugins] = useState<PluginInfo[]>([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState<string | null>(null);
@ -32,7 +35,7 @@ export default function PluginsPage() {
const data = await listPlugins();
setPlugins(Array.isArray(data) ? data : []);
} catch (err: any) {
setError(err.message || '加载插件失败');
setError(err.message || pickAppText(locale, '加载插件失败', 'Failed to load plugins'));
} finally {
setLoading(false);
}
@ -57,15 +60,16 @@ export default function PluginsPage() {
<div>
<h1 className="text-2xl font-bold flex items-center gap-2">
<Blocks className="w-6 h-6" />
{pickAppText(locale, '插件', 'Plugins')}
</h1>
<p className="text-sm text-muted-foreground mt-1">
workspace <code className="text-xs bg-muted px-1 py-0.5 rounded">plugins/</code>
{pickAppText(locale, '已安装位置:全局插件目录或当前 workspace 的 ', 'Installed from the global plugin directory or this workspace\'s ')}
<code className="text-xs bg-muted px-1 py-0.5 rounded">plugins/</code>
</p>
</div>
<Button onClick={load} variant="outline" size="sm">
<RefreshCw className="w-4 h-4 mr-2" />
{pickAppText(locale, '刷新', 'Refresh')}
</Button>
</div>
@ -86,10 +90,11 @@ export default function PluginsPage() {
<Card>
<CardContent className="py-16 text-center text-muted-foreground">
<Blocks className="w-12 h-12 mx-auto mb-4 opacity-30" />
<p className="font-medium"></p>
<p className="font-medium">{pickAppText(locale, '还没有安装任何插件', 'No plugins are installed yet')}</p>
<p className="text-sm mt-2 max-w-sm mx-auto">
workspace <code className="text-xs bg-muted px-1 py-0.5 rounded">plugins/</code>
Boardware Agent Sandbox
{pickAppText(locale, '把插件目录放到全局插件目录或当前 workspace 的 ', 'Put a plugin directory in the global plugin directory or this workspace\'s ')}
<code className="text-xs bg-muted px-1 py-0.5 rounded">plugins/</code>
{pickAppText(locale, ',然后重启 Boardware Agent Sandbox。', ', then restart Boardware Agent Sandbox.')}
</p>
</CardContent>
</Card>
@ -106,6 +111,7 @@ export default function PluginsPage() {
}
function PluginCard({ plugin }: { plugin: PluginInfo }) {
const { locale } = useAppI18n();
const [agentsOpen, setAgentsOpen] = useState(true);
const [commandsOpen, setCommandsOpen] = useState(true);
const [skillsOpen, setSkillsOpen] = useState(false);
@ -132,19 +138,19 @@ function PluginCard({ plugin }: { plugin: PluginInfo }) {
{plugin.agents.length > 0 && (
<span className="flex items-center gap-1 text-xs bg-muted px-2 py-0.5 rounded-full">
<Bot className="w-3 h-3" />
{plugin.agents.length}
{pickAppText(locale, `${plugin.agents.length} 个智能体`, `${plugin.agents.length} agents`)}
</span>
)}
{plugin.commands.length > 0 && (
<span className="flex items-center gap-1 text-xs bg-muted px-2 py-0.5 rounded-full">
<Terminal className="w-3 h-3" />
{plugin.commands.length}
{pickAppText(locale, `${plugin.commands.length} 条命令`, `${plugin.commands.length} commands`)}
</span>
)}
{plugin.skills.length > 0 && (
<span className="flex items-center gap-1 text-xs bg-muted px-2 py-0.5 rounded-full">
<Wrench className="w-3 h-3" />
{plugin.skills.length}
{pickAppText(locale, `${plugin.skills.length} 个技能`, `${plugin.skills.length} skills`)}
</span>
)}
</div>
@ -157,7 +163,7 @@ function PluginCard({ plugin }: { plugin: PluginInfo }) {
{plugin.agents.length > 0 && (
<Section
icon={<Bot className="w-3.5 h-3.5" />}
label="智能体"
label={pickAppText(locale, '智能体', 'Agents')}
count={plugin.agents.length}
open={agentsOpen}
onToggle={() => setAgentsOpen((v) => !v)}
@ -186,7 +192,7 @@ function PluginCard({ plugin }: { plugin: PluginInfo }) {
{plugin.commands.length > 0 && (
<Section
icon={<Terminal className="w-3.5 h-3.5" />}
label="命令"
label={pickAppText(locale, '命令', 'Commands')}
count={plugin.commands.length}
open={commandsOpen}
onToggle={() => setCommandsOpen((v) => !v)}
@ -213,7 +219,7 @@ function PluginCard({ plugin }: { plugin: PluginInfo }) {
{plugin.skills.length > 0 && (
<Section
icon={<Wrench className="w-3.5 h-3.5" />}
label="技能"
label={pickAppText(locale, '技能', 'Skills')}
count={plugin.skills.length}
open={skillsOpen}
onToggle={() => setSkillsOpen((v) => !v)}
@ -234,18 +240,19 @@ function PluginCard({ plugin }: { plugin: PluginInfo }) {
}
function SourceBadge({ source }: { source: 'global' | 'workspace' }) {
const { locale } = useAppI18n();
if (source === 'workspace') {
return (
<Badge variant="default" className="text-xs gap-1">
<FolderOpen className="w-3 h-3" />
{pickAppText(locale, '工作区', 'Workspace')}
</Badge>
);
}
return (
<Badge variant="secondary" className="text-xs gap-1">
<Globe className="w-3 h-3" />
{pickAppText(locale, '全局', 'Global')}
</Badge>
);
}