diff --git a/frontend-web/src/roundtable-planning/hooks/useStep2Orchestration.ts b/frontend-web/src/roundtable-planning/hooks/useStep2Orchestration.ts index 72089437..032fa03d 100644 --- a/frontend-web/src/roundtable-planning/hooks/useStep2Orchestration.ts +++ b/frontend-web/src/roundtable-planning/hooks/useStep2Orchestration.ts @@ -1201,8 +1201,9 @@ export function useStep2Orchestration( if (speakerId !== null && item.id === speakerId) { return { ...item, status: "研讨中" }; } + // 发言结束(不再研讨中)的席位标记为「已完成」,而非回退到「在线」。 if (item.status === "研讨中") { - return { ...item, status: "在线" }; + return { ...item, status: "已完成" }; } return item; }), @@ -1215,7 +1216,7 @@ export function useStep2Orchestration( (speakerId: number) => { // 编排循环已经改成**顺序**派 special(详见 §5.4 / 文件顶部注释), // 任意时刻只有一个子智能体在跑。因此这里既要把当前发言席位置为"研讨中", - // 又要把上一轮 / 历史残留下来的"研讨中"统一清成"在线",保证右侧"参与角色" + // 又要把上一轮 / 历史残留下来的"研讨中"统一标记成"已完成",保证右侧"参与角色" // 面板任何时刻**只有一个** sub agent 显示研讨中,与对话区实际在 stream 的 // 那一个一致。activeSpeakerSet 沿用 Set 形态(虽然实际只放 1 个)以兼容外部 // 消费方,真正的"高亮排他"靠 roles 的 status reset。 @@ -1223,7 +1224,8 @@ export function useStep2Orchestration( setRoles((prev) => prev.map((item) => { if (item.id === speakerId) return { ...item, status: "研讨中" }; - if (item.status === "研讨中") return { ...item, status: "在线" }; + // 上一轮发言已结束的席位标记为「已完成」,而非回退到「在线」。 + if (item.status === "研讨中") return { ...item, status: "已完成" }; return item; }), ); @@ -1241,8 +1243,9 @@ export function useStep2Orchestration( }); setRoles((prev) => prev.map((item) => + // 该席位本轮输出完成 —— 标记为「已完成」(带勾选样式),而非回退到「在线」。 item.id === speakerId && item.status === "研讨中" - ? { ...item, status: "在线" } + ? { ...item, status: "已完成" } : item, ), ); @@ -1254,14 +1257,15 @@ export function useStep2Orchestration( setActiveSpeakerSet(new Set()); setRoles((prev) => prev.map((item) => - item.status === "研讨中" ? { ...item, status: "在线" } : item, + // 研讨收尾:仍在研讨中的席位置为「已完成」,而非回退到「在线」。 + item.status === "研讨中" ? { ...item, status: "已完成" } : item, ), ); }, [setRoles]); /** * DAG 并行批次:把**一整批**席位同时标为「研讨中」(与 markSpeakerStreaming - * 的"排他单发"不同 —— 并行就是要多个 sub 同时高亮)。其余历史残留的"研讨中"清成"在线"。 + * 的"排他单发"不同 —— 并行就是要多个 sub 同时高亮)。其余历史残留的"研讨中"标记成"已完成"。 * activeSpeakerSet 天然是 Set,这里放整批 speakerId。 */ const markParallelSpeakers = useCallback( @@ -1271,7 +1275,8 @@ export function useStep2Orchestration( setRoles((prev) => prev.map((item) => { if (wanted.has(item.id)) return { ...item, status: "研讨中" }; - if (item.status === "研讨中") return { ...item, status: "在线" }; + // 上一并行批次发言已结束的席位标记为「已完成」,而非回退到「在线」。 + if (item.status === "研讨中") return { ...item, status: "已完成" }; return item; }), ); diff --git a/frontend-web/src/roundtable-planning/pages/RoundtablePlanningPage.tsx b/frontend-web/src/roundtable-planning/pages/RoundtablePlanningPage.tsx index bcf6cd2b..c382ceba 100644 --- a/frontend-web/src/roundtable-planning/pages/RoundtablePlanningPage.tsx +++ b/frontend-web/src/roundtable-planning/pages/RoundtablePlanningPage.tsx @@ -2422,6 +2422,7 @@ function RoleAvatarBadge({ onSelect?: () => void; }) { const isOngoing = role.status === "研讨中"; + const isDone = role.status === "已完成"; const animate = showSpeakingAnimation && isOngoing; const clickable = Boolean(onSelect); @@ -2439,6 +2440,12 @@ function RoleAvatarBadge({
{renderRoleAvatar(role, agentNameToRole, size)}
+ {/* 收起态:输出完成的席位在头像右下角叠加「已完成」勾选角标。 */} + {isDone && ( + + + + )} );