feat(desktop): T0.2 多智能体进 Studio —— coordinator 节点 + 专家卡片 + 派发可观测

把已通的多智能体后端(MULTI_AGENT.md)接上 UI,用户可在画布拖出协调者图。

- nodeCatalog: 新增 `coordinator`「多智能体协调」节点(indigo) + 新字段类型
  `agentList` + Specialist 接口({name,use,system,tools}),与后端 parseSpecialists 对齐。
- Inspector: AgentListField —— 可增删的子智能体卡片(名/用途/系统提示词/工具逗号分隔)。
- dsl 校验: agentList 需 ≥1 个有名字的专家、名字不重复。
- RunsView: 「工具调用」面板纳入专家派发(kind=agent),改名「工具/专家」,专家项
  用 Users 图标 + indigo「专家」徽标区分(此前只筛 kind=tool,漏掉多智能体派发)。
- 导出: agents 数组经 exportDsl 原样透传进 DSL → 后端 parseSpecialists 直接消费。

tsc + vitest(19) 绿;UI 同款结构 DSL 后端可跑(协调链路 live 已验)。
DEPTH_ROADMAP T0.2 ,T0 激活 2/2 完成。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Blizzard
2026-06-29 17:14:14 +08:00
parent 158fe094ab
commit cb6eec5614
5 changed files with 116 additions and 31 deletions
+10
View File
@@ -52,6 +52,16 @@ export function validate(nodes: Node[], edges: Edge[]): Issue[] {
.filter((f) => f.required)
.forEach((f) => {
const v = d.config?.[f.key];
if (f.type === "agentList") {
const arr = Array.isArray(v) ? (v as Array<{ name?: string }>) : [];
const names = arr.map((s) => s?.name?.trim()).filter(Boolean) as string[];
if (names.length === 0) {
issues.push({ level: "warn", msg: `节点「${d.label || k.label}」至少需要一个有名字的专家` });
} else if (new Set(names).size !== names.length) {
issues.push({ level: "warn", msg: `节点「${d.label || k.label}」专家名有重复` });
}
return;
}
if (v === undefined || v === "" || String(v).startsWith("(未")) {
issues.push({ level: "warn", msg: `节点「${d.label || k.label}」缺必填项:${f.label}` });
}