subagent-lineage.client.spec.ts 1.8 KB

12345678910111213141516171819202122232425262728293031
  1. import { describe, expect, it } from 'vitest'
  2. import type { SessionId } from '@deepseek-ai/dsh-session/types'
  3. import { indexSubagentDescendants } from '../src/client/subagent-lineage.ts'
  4. const sid = (id: string): SessionId => id as SessionId
  5. describe('UI Subagent descendant projection', () => {
  6. it('counts nested running descendants and stops at ordinary forks', () => {
  7. const owner = { id: sid('owner'), running: false }
  8. const child = { id: sid('child'), parentId: owner.id, origin: 'subagent' as const, running: false }
  9. const grandchild = { id: sid('grandchild'), parentId: child.id, origin: 'subagent' as const, running: true }
  10. const fork = { id: sid('fork'), parentId: child.id, running: false }
  11. const forkChild = { id: sid('fork-child'), parentId: fork.id, origin: 'subagent' as const, running: true }
  12. const result = indexSubagentDescendants(Object.fromEntries(
  13. [owner, child, grandchild, fork, forkChild].map(item => [item.id, item]),
  14. ))
  15. expect(result.get(owner.id)).toEqual({ count: 2, runningCount: 1 })
  16. expect(result.get(child.id)).toEqual({ count: 1, runningCount: 1 })
  17. expect(result.get(fork.id)).toEqual({ count: 1, runningCount: 1 })
  18. })
  19. it('terminates cycles and retains missing-parent aggregates', () => {
  20. const cycleA = { id: sid('a'), parentId: sid('b'), origin: 'subagent' as const, running: false }
  21. const cycleB = { id: sid('b'), parentId: sid('a'), origin: 'subagent' as const, running: false }
  22. const orphan = { id: sid('orphan'), parentId: sid('missing'), origin: 'subagent' as const, running: true }
  23. const result = indexSubagentDescendants({ [cycleA.id]: cycleA, [cycleB.id]: cycleB, [orphan.id]: orphan })
  24. expect(result.get(cycleA.id)?.count).toBe(2)
  25. expect(result.get(cycleB.id)?.count).toBe(2)
  26. expect(result.get(sid('missing'))).toEqual({ count: 1, runningCount: 1 })
  27. })
  28. })