feat(tasks): 空闲成员 ≥3 时自动收进聚合,聚合并如实报出状态配比
用户要求优化显示:「比如空闲时也折叠」。 在此之前,一个跑完一轮的 teammate(活体通道不报 running)映射成 idle, 而 idle 不在「已完成/出错」的可折叠集合里 —— 于是 8 人团队永远摆 8 张卡, 而同样「不在执行」的普通子代理却是 done、会折叠。同一事实两种显示,才是 这个痛点的根。 - 可折叠集合放宽到「不在执行」(done | idle | error);运行中/部署中永不折叠。 - 空闲**不无条件收**:按用户确认的阈值,一个父节点下空闲成员 ≥3 才随页面级 折叠规则一起收(FOLD_IDLE_MIN)。1–2 个待命成员就是这个团队的工作集, 而且它们的卡上会挂任务行,留着看;3 个以上才是「在扫名册」。 - 聚合行如实报账:聚合节点新增 doneCount/idleCount/errorCount/hasIdle, 小条写 `✓ N 已完成 · N 待命 · 出错 N`(为零的项省略,全已完成时与原先一样短), 徽标在**没有已完成项**时改说 `N 待命` —— 否则「✓ N 已完成」会把待命和出错 一起算成已完成,是撒谎。图卡片与树行共用 foldTally/foldBadgeCount。 - 手动折叠(卡片 chevron)不设阈值:那是读者点名要收的节点。 - i18n:新增 tasksFoldIdle ×20 词典。 测试:新增 6 例(阈值命中收 3 个空闲成员、2 个保持可见、运行中成员即使达标也不收、 混合聚合按状态计数、页面聚合行报「3 待命」且徽标不说已完成);pnpm test 1284 passed / 9 skipped,typecheck / lint 通过。 (cherry picked from commit 39d66ffb2e93eeb4095ec1cb2ac15933cce62742)
This commit is contained in:
@@ -18,7 +18,9 @@ import {
|
||||
} from '@deepseek-ai/dsh-client-ui-primitives'
|
||||
import type { SidebarChildLiveView } from '../context-types.ts'
|
||||
import { liveActivityLabel } from './process-labels.ts'
|
||||
import type { TasksAgentNode, TasksNodeState, TasksNodeTask, TasksWorkflowNode } from './tasks-model.ts'
|
||||
import type {
|
||||
TasksAgentNode, TasksFoldNode, TasksNodeState, TasksNodeTask, TasksWorkflowNode,
|
||||
} from './tasks-model.ts'
|
||||
import { toolGlyph } from './tool-icons.tsx'
|
||||
import { t, type CopyKey } from './locales.ts'
|
||||
import css from './tasks-graph.module.css'
|
||||
@@ -280,7 +282,28 @@ export function LiveLine(props: { live: SidebarChildLiveView | undefined }): Rea
|
||||
)
|
||||
}
|
||||
|
||||
/** The fold aggregate's subtitle: up to two label previews joined by ·. */
|
||||
/** The fold aggregate's subtitle: up to two label previews joined by `/`. */
|
||||
export function foldPreviews(previews: readonly string[]): string {
|
||||
return previews.join(' / ')
|
||||
}
|
||||
|
||||
/**
|
||||
* The fold aggregate's state tally — `✓ 2 已完成 · 3 待命 · 1 出错`.
|
||||
*
|
||||
* The aggregate has to SAY what it swallowed: the badge's "✓ N 已完成" is
|
||||
* true only for the settled part, and an aggregate that also sweeps idle
|
||||
* members (or errors) would otherwise read as a lie. Parts that are zero are
|
||||
* omitted, so an all-done aggregate stays exactly as short as it was.
|
||||
*/
|
||||
export function foldTally(node: TasksFoldNode): string {
|
||||
const parts: string[] = []
|
||||
if (node.doneCount > 0) parts.push(t('tasksFoldCompleted', { count: node.doneCount }))
|
||||
if (node.idleCount > 0) parts.push(t('tasksFoldIdle', { count: node.idleCount }))
|
||||
if (node.errorCount > 0) parts.push(`${t('tasksStateError')} ${node.errorCount}`)
|
||||
return parts.join(' · ')
|
||||
}
|
||||
|
||||
/** The aggregate's cross-state badge word: 已完成 unless nothing is done. */
|
||||
export function foldBadgeCount(node: TasksFoldNode): number {
|
||||
return node.doneCount > 0 ? node.doneCount : node.count
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user