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

@ -7,33 +7,9 @@ import { Badge } from '@/components/ui/badge';
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
import { ScrollArea } from '@/components/ui/scroll-area';
import { Separator } from '@/components/ui/separator';
function statusLabel(status: string) {
if (status === 'done') return '已完成';
if (status === 'error') return '失败';
if (status === 'cancelled') return '已取消';
if (status === 'waiting') return '等待中';
if (status === 'running') return '运行中';
if (status === 'queued') return '排队中';
return status;
}
function actorTypeLabel(actorType: string) {
if (actorType === 'mcp') return 'MCP';
if (actorType === 'system') return '系统';
if (actorType === 'agent') return '智能体';
return actorType;
}
function eventKindLabel(kind: string) {
if (kind === 'run_started') return '已启动';
if (kind === 'run_progress') return '进行中';
if (kind === 'run_status') return '状态更新';
if (kind === 'run_artifact') return '产物';
if (kind === 'run_finished') return '已结束';
if (kind === 'run_cancelled') return '已取消';
return kind;
}
import { appActorTypeLabel, appEventKindLabel, appStatusLabel } from '@/lib/i18n/common';
import { pickAppText } from '@/lib/i18n/core';
import { useAppI18n } from '@/lib/i18n/provider';
function artifactIcon(type: ProcessArtifact['artifact_type']) {
if (type === 'json') return <FileJson className="w-4 h-4" />;
@ -42,7 +18,7 @@ function artifactIcon(type: ProcessArtifact['artifact_type']) {
return <FileOutput className="w-4 h-4" />;
}
function renderArtifactBody(artifact: ProcessArtifact) {
function renderArtifactBody(artifact: ProcessArtifact, locale: 'zh-CN' | 'en-US') {
if (artifact.artifact_type === 'json' && artifact.data !== undefined) {
return (
<pre className="text-[11px] leading-5 whitespace-pre-wrap break-words rounded-md bg-background/70 p-3 overflow-x-auto">
@ -59,7 +35,7 @@ function renderArtifactBody(artifact: ProcessArtifact) {
}
return (
<div className="text-xs text-foreground/90 whitespace-pre-wrap break-words">
{artifact.content || '(空产物)'}
{artifact.content || pickAppText(locale, '(空产物)', '(Empty artifact)')}
</div>
);
}
@ -73,6 +49,7 @@ export function ArtifactSidebar({
events: ProcessEvent[];
artifacts: ProcessArtifact[];
}) {
const { locale } = useAppI18n();
const runArtifacts = selectedRun
? artifacts.filter((item) => item.run_id === selectedRun.run_id)
: artifacts;
@ -90,9 +67,11 @@ export function ArtifactSidebar({
return (
<div className="h-full bg-card/60 flex flex-col border-l border-border">
<div className="px-4 py-3 border-b border-border">
<h2 className="text-sm font-semibold tracking-wide uppercase text-muted-foreground"></h2>
<h2 className="text-sm font-semibold tracking-wide uppercase text-muted-foreground">{pickAppText(locale, '结果面板', 'Results')}</h2>
<p className="text-xs text-muted-foreground mt-1">
{selectedRun ? `当前选中: ${selectedRun.actor_name}` : '选择一个任务查看详细过程与产物'}
{selectedRun
? pickAppText(locale, `当前选中: ${selectedRun.actor_name}`, `Selected: ${selectedRun.actor_name}`)
: pickAppText(locale, '选择一个任务查看详细过程与产物', 'Select a task to inspect its process and artifacts')}
</p>
</div>
<ScrollArea className="flex-1 px-4 py-4">
@ -101,24 +80,24 @@ export function ArtifactSidebar({
<CardHeader className="pb-3">
<CardTitle className="text-sm flex items-center gap-2">
<FolderSearch className="w-4 h-4" />
{pickAppText(locale, '任务摘要', 'Task summary')}
</CardTitle>
</CardHeader>
<CardContent className="pt-0 space-y-2 text-sm">
{selectedRun ? (
<>
<div className="flex items-center gap-2 flex-wrap">
<Badge variant="outline">{actorTypeLabel(selectedRun.actor_type)}</Badge>
<Badge variant="outline">{statusLabel(selectedRun.status)}</Badge>
<Badge variant="outline">{appActorTypeLabel(selectedRun.actor_type, locale)}</Badge>
<Badge variant="outline">{appStatusLabel(selectedRun.status, locale)}</Badge>
{selectedRun.source && <Badge variant="secondary">{selectedRun.source}</Badge>}
</div>
<div className="font-medium">{selectedRun.title}</div>
<div className="text-muted-foreground whitespace-pre-wrap break-words">
{selectedRun.summary || '暂时还没有最终摘要。'}
{selectedRun.summary || pickAppText(locale, '暂时还没有最终摘要。', 'No final summary yet.')}
</div>
</>
) : (
<div className="text-muted-foreground text-sm"></div>
<div className="text-muted-foreground text-sm">{pickAppText(locale, '当前没有选中的任务。', 'No task is selected right now.')}</div>
)}
</CardContent>
</Card>
@ -127,22 +106,22 @@ export function ArtifactSidebar({
<CardHeader className="pb-3">
<CardTitle className="text-sm flex items-center gap-2">
<MessagesSquare className="w-4 h-4" />
{pickAppText(locale, '事件记录', 'Events')}
</CardTitle>
</CardHeader>
<CardContent className="pt-0 space-y-2">
{runEvents.length === 0 && (
<div className="text-xs text-muted-foreground"></div>
<div className="text-xs text-muted-foreground">{pickAppText(locale, '暂时还没有结构化事件。', 'No structured events yet.')}</div>
)}
{runEvents.map((event, index) => (
<div key={event.event_id}>
<div className="rounded-md border border-border/60 px-3 py-2 bg-background/60">
<div className="flex items-center gap-2 text-[10px] uppercase tracking-wide text-muted-foreground mb-1">
<span>{eventKindLabel(event.kind)}</span>
{event.status && <span>{statusLabel(event.status)}</span>}
<span>{appEventKindLabel(event.kind, locale)}</span>
{event.status && <span>{appStatusLabel(event.status, locale)}</span>}
</div>
<div className="text-xs whitespace-pre-wrap break-words">
{event.text || '结构化更新'}
{event.text || pickAppText(locale, '结构化更新', 'Structured update')}
</div>
</div>
{index < runEvents.length - 1 && <Separator className="my-2" />}
@ -155,12 +134,12 @@ export function ArtifactSidebar({
<CardHeader className="pb-3">
<CardTitle className="text-sm flex items-center gap-2">
<FileOutput className="w-4 h-4" />
{pickAppText(locale, '产物列表', 'Artifacts')}
</CardTitle>
</CardHeader>
<CardContent className="pt-0 space-y-3">
{runArtifacts.length === 0 && (
<div className="text-xs text-muted-foreground"></div>
<div className="text-xs text-muted-foreground">{pickAppText(locale, '暂时还没有产物。', 'No artifacts yet.')}</div>
)}
{runArtifacts.map((artifact) => (
<div key={artifact.artifact_id} className="rounded-lg border border-border/70 bg-background/70 p-3 space-y-2">
@ -175,7 +154,7 @@ export function ArtifactSidebar({
</div>
</div>
</div>
{renderArtifactBody(artifact)}
{renderArtifactBody(artifact, locale)}
</div>
))}
</CardContent>